namespace Dali
{
-
struct UniformData
{
- std::string name;
- Property::Type type;
- UniformData( const std::string& name, Property::Type type = Property::Type::NONE)
- : name(name), type(type)
- {}
+ std::string name;
+ Property::Type type;
+ UniformData(const std::string& name, Property::Type type = Property::Type::NONE)
+ : name(name),
+ type(type)
+ {
+ }
};
class DALI_CORE_API TestGlAbstraction : public Dali::Integration::GlAbstraction
GetUniformLocation(program, "uLightCameraProjectionMatrix");
GetUniformLocation(program, "uLightCameraViewMatrix");
- for( const auto& uniform : mCustomUniformData )
+ for(const auto& uniform : mCustomUniformData)
{
GetUniformLocation(program, uniform.name.c_str());
}
typedef std::map<GLuint, UniformIDMap> ProgramUniformMap;
ProgramUniformMap mUniforms;
- std::vector<UniformData> mCustomUniformData{};
+ std::vector<UniformData> mCustomUniformData{};
template<typename T>
struct ProgramUniformValue : public std::map<GLuint, std::map<GLint, T> >
*/
#include "test-graphics-buffer.h"
-#include "test-graphics-program.h"
-#include "test-graphics-reflection.h"
#include <sstream>
#include "dali-test-suite-utils.h"
+#include "test-graphics-program.h"
+#include "test-graphics-reflection.h"
namespace Dali
{
mGl(glAbstraction),
mUsage(usage)
{
- memory.reserve(size);
+ memory.resize(size);
mGl.GetBufferTrace().EnableLogging(true);
}
return target;
}
-void TestGraphicsBuffer::BindAsUniformBuffer( const TestGraphicsProgram* program ) const
+void TestGraphicsBuffer::BindAsUniformBuffer(const TestGraphicsProgram* program) const
{
auto* reflection = static_cast<const TestGraphicsReflection*>(&program->GetReflection());
auto* data = memory.data();
- for( const auto& member : uboInfo.members )
+ for(const auto& member : uboInfo.members)
{
- auto type = reflection->GetMemberType( 0, member.location );
+ auto type = reflection->GetMemberType(0, member.location);
switch(type)
{
case Property::VECTOR4:
{
- auto value = *reinterpret_cast<const Dali::Vector4*>(data+member.offset);
- mGl.Uniform4f( member.location, value.x, value.y, value.z, value.w );
+ auto value = *reinterpret_cast<const Dali::Vector4*>(data + member.offset);
+ mGl.Uniform4f(member.location, value.x, value.y, value.z, value.w);
break;
}
case Property::VECTOR3:
{
- auto value = *reinterpret_cast<const Dali::Vector3*>(data+member.offset);
- mGl.Uniform3f( member.location, value.x, value.y, value.z );
+ auto value = *reinterpret_cast<const Dali::Vector3*>(data + member.offset);
+ mGl.Uniform3f(member.location, value.x, value.y, value.z);
break;
}
case Property::VECTOR2:
{
- auto value = *reinterpret_cast<const Dali::Vector2*>(data+member.offset);
- mGl.Uniform2f( member.location, value.x, value.y );
+ auto value = *reinterpret_cast<const Dali::Vector2*>(data + member.offset);
+ mGl.Uniform2f(member.location, value.x, value.y);
break;
}
case Property::FLOAT:
{
- auto value = *reinterpret_cast<const float*>(data+member.offset);
- mGl.Uniform1f( member.location, value );
+ auto value = *reinterpret_cast<const float*>(data + member.offset);
+ mGl.Uniform1f(member.location, value);
break;
}
case Property::INTEGER:
{
- auto ptr = reinterpret_cast<const GLint*>(data+member.offset);
+ auto ptr = reinterpret_cast<const GLint*>(data + member.offset);
auto value = *ptr;
- mGl.Uniform1i( member.location, value );
+ mGl.Uniform1i(member.location, value);
break;
}
case Property::MATRIX:
{
- auto value = reinterpret_cast<const float*>(data+member.offset);
- mGl.UniformMatrix4fv( member.location, 1, GL_FALSE, value );
+ auto value = reinterpret_cast<const float*>(data + member.offset);
+ mGl.UniformMatrix4fv(member.location, 1, GL_FALSE, value);
break;
}
case Property::MATRIX3:
{
- auto value = reinterpret_cast<const float*>(data+member.offset);
- mGl.UniformMatrix3fv( member.location, 1, GL_FALSE, value );
+ auto value = reinterpret_cast<const float*>(data + member.offset);
+ mGl.UniformMatrix3fv(member.location, 1, GL_FALSE, value);
break;
}
default:
{
-
+ fprintf(stderr, "\n%s type not found\n", member.name.c_str());
}
}
}
-
-
}
} // namespace Dali
return true;
}
- void BindAsUniformBuffer( const TestGraphicsProgram* program ) const;
+ void BindAsUniformBuffer(const TestGraphicsProgram* program) const;
TraceCallStack& mCallStack;
TestGlAbstraction& mGl;
int TestGraphicsCommandBuffer::GetDrawCallsCount()
{
int count = 0;
- for( auto& cmd : mCommands )
+ for(auto& cmd : mCommands)
{
- if( cmd.type == CommandType::DRAW ||
- cmd.type == CommandType::DRAW_INDEXED ||
- cmd.type == CommandType::DRAW_INDEXED_INDIRECT )
+ if(cmd.type == CommandType::DRAW ||
+ cmd.type == CommandType::DRAW_INDEXED ||
+ cmd.type == CommandType::DRAW_INDEXED_INDIRECT)
{
++count;
}
return count;
}
-void TestGraphicsCommandBuffer::GetStateForDrawCall( int drawCallIndex )
+void TestGraphicsCommandBuffer::GetStateForDrawCall(int drawCallIndex)
{
- int index = 0;
+ int index = 0;
std::vector<Command> mCommandStack{};
- for( auto& cmd : mCommands )
+ for(auto& cmd : mCommands)
{
mCommandStack.push_back(cmd);
- if( cmd.type == CommandType::DRAW ||
- cmd.type == CommandType::DRAW_INDEXED ||
- cmd.type == CommandType::DRAW_INDEXED_INDIRECT )
+ if(cmd.type == CommandType::DRAW ||
+ cmd.type == CommandType::DRAW_INDEXED ||
+ cmd.type == CommandType::DRAW_INDEXED_INDIRECT)
{
- if( index == drawCallIndex )
+ if(index == drawCallIndex)
{
break;
}
}
}
-std::vector<Command*> TestGraphicsCommandBuffer::GetCommandsByType( CommandTypeMask mask )
+std::vector<Command*> TestGraphicsCommandBuffer::GetCommandsByType(CommandTypeMask mask)
{
std::vector<Command*> mCommandStack{};
- for( auto& cmd : mCommands )
+ for(auto& cmd : mCommands)
{
- if(uint32_t(cmd.type) == (mask & uint32_t(cmd.type)) )
+ if(uint32_t(cmd.type) == (mask & uint32_t(cmd.type)))
{
- mCommandStack.emplace_back( &cmd );
+ mCommandStack.emplace_back(&cmd);
}
}
return mCommandStack;
#include <cstdint>
#include <vector>
#include "test-gl-abstraction.h"
-#include "test-graphics-pipeline.h"
#include "test-graphics-buffer.h"
+#include "test-graphics-pipeline.h"
#include "test-trace-call-stack.h"
namespace Dali
enum class CommandType
{
- FLUSH = 1 << 0,
- BIND_TEXTURES = 1 << 1,
- BIND_SAMPLERS = 1 << 2,
- BIND_VERTEX_BUFFERS = 1 << 3,
- BIND_INDEX_BUFFER = 1 << 4,
- BIND_UNIFORM_BUFFER = 1 << 5,
- BIND_PIPELINE = 1 << 6,
- DRAW = 1 << 7,
- DRAW_INDEXED = 1 << 8,
- DRAW_INDEXED_INDIRECT = 1 << 9
+ FLUSH = 1 << 0,
+ BIND_TEXTURES = 1 << 1,
+ BIND_SAMPLERS = 1 << 2,
+ BIND_VERTEX_BUFFERS = 1 << 3,
+ BIND_INDEX_BUFFER = 1 << 4,
+ BIND_UNIFORM_BUFFER = 1 << 5,
+ BIND_PIPELINE = 1 << 6,
+ DRAW = 1 << 7,
+ DRAW_INDEXED = 1 << 8,
+ DRAW_INDEXED_INDIRECT = 1 << 9,
+ SET_SCISSOR = 1 << 10,
+ SET_SCISSOR_TEST = 1 << 11,
+ SET_VIEWPORT = 1 << 12,
+ SET_VIEWPORT_TEST = 1 << 13
};
using CommandTypeMask = uint32_t;
struct VertexBufferBindingDescriptor
{
const TestGraphicsBuffer* buffer{nullptr};
- uint32_t offset{0u};
+ uint32_t offset{0u};
};
/**
struct IndexBufferBindingDescriptor
{
const TestGraphicsBuffer* buffer{nullptr};
- uint32_t offset{};
- Graphics::Format format{};
+ uint32_t offset{};
+ Graphics::Format format{};
};
/**
struct UniformBufferBindingDescriptor
{
const TestGraphicsBuffer* buffer{nullptr};
- uint32_t binding{0u};
- uint32_t offset{0u};
- bool emulated; ///<true if UBO is emulated for old gfx API
+ uint32_t binding{0u};
+ uint32_t offset{0u};
+ bool emulated; ///<true if UBO is emulated for old gfx API
};
/**
struct
{
const TestGraphicsBuffer* buffer;
- uint32_t offset;
- uint32_t drawCount;
- uint32_t stride;
+ uint32_t offset;
+ uint32_t drawCount;
+ uint32_t stride;
} drawIndexedIndirect;
};
};
// Nothing to do
break;
}
+ case CommandType::SET_SCISSOR:
+ {
+ data.scissor.region = rhs.data.scissor.region;
+ break;
+ }
+ case CommandType::SET_SCISSOR_TEST:
+ {
+ data.scissorTest.enable = rhs.data.scissorTest.enable;
+ break;
+ }
+ case CommandType::SET_VIEWPORT:
+ {
+ data.viewport.region = rhs.data.viewport.region;
+ break;
+ }
+ case CommandType::SET_VIEWPORT_TEST:
+ {
+ data.viewportTest.enable = rhs.data.viewportTest.enable;
+ break;
+ }
}
type = rhs.type;
}
/**
- * @brief Copy constructor
+ * @brief move constructor
* @param[in] rhs Command
*/
Command(Command&& rhs) noexcept
// Nothing to do
break;
}
+ case CommandType::SET_SCISSOR:
+ {
+ data.scissor.region = rhs.data.scissor.region;
+ break;
+ }
+ case CommandType::SET_SCISSOR_TEST:
+ {
+ data.scissorTest.enable = rhs.data.scissorTest.enable;
+ break;
+ }
+ case CommandType::SET_VIEWPORT:
+ {
+ data.viewport.region = rhs.data.viewport.region;
+ break;
+ }
+ case CommandType::SET_VIEWPORT_TEST:
+ {
+ data.viewportTest.enable = rhs.data.viewportTest.enable;
+ break;
+ }
}
type = rhs.type;
}
struct : public DrawCallDescriptor
{
} draw;
+
+ struct
+ {
+ Graphics::Rect2D region;
+ } scissor;
+ struct
+ {
+ bool enable;
+ } scissorTest;
+ struct
+ {
+ Graphics::Viewport region;
+ } viewport;
+ struct
+ {
+ bool enable;
+ } viewportTest;
} data;
};
-
class TestGraphicsCommandBuffer : public Graphics::CommandBuffer
{
public:
TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction);
~TestGraphicsCommandBuffer()
{
-
}
void BindVertexBuffers(uint32_t firstBinding,
void BindIndexBuffer(const Graphics::Buffer& buffer,
uint32_t offset,
- Graphics::Format format) override
+ Graphics::Format format) override
{
mCommands.emplace_back();
mCommands.back().type = CommandType::BIND_INDEX_BUFFER;
}
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("Reset", "");
}
- void SetScissor(Graphics::Extent2D value) override
+ void SetScissor(Graphics::Rect2D value) override
{
- mCallStack.PushCall("SetScissor", "");
+ TraceCallStack::NamedParams params;
+ params["x"] << value.x;
+ params["y"] << value.y;
+ params["width"] << value.width;
+ params["height"] << value.height;
+ mCallStack.PushCall("SetScissor", params.str(), params);
+
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_SCISSOR;
+ mCommands.back().data.scissor.region = value;
}
void SetScissorTestEnable(bool value) override
{
- mCallStack.PushCall("SetScissorTestEnable", "");
+ TraceCallStack::NamedParams params;
+ params["value"] << (value ? "T" : "F");
+ mCallStack.PushCall("SetScissorTestEnable", params.str(), params);
+
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_SCISSOR_TEST;
+ mCommands.back().data.scissorTest.enable = value;
}
void SetViewport(Graphics::Viewport value) override
{
- mCallStack.PushCall("SetViewport", "");
+ TraceCallStack::NamedParams params;
+ params["x"] << value.x;
+ params["y"] << value.y;
+ params["width"] << value.width;
+ params["height"] << value.height;
+ params["minDepth"] << value.minDepth;
+ params["maxDepth"] << value.maxDepth;
+ mCallStack.PushCall("SetViewport", params.str(), params);
+
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_VIEWPORT;
+ mCommands.back().data.viewport.region = value;
}
void SetViewportEnable(bool value) override
{
- mCallStack.PushCall("SetViewportEnable", "");
+ TraceCallStack::NamedParams params;
+ params["value"] << (value ? "T" : "F");
+ mCallStack.PushCall("SetViewportEnable", params.str(), params);
+
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::SET_VIEWPORT_TEST;
+ mCommands.back().data.viewportTest.enable = value;
}
[[nodiscard]] const std::vector<Command>& GetCommands() const
* Retrieves state resolve for selected draw call
* @param drawCommandIndex
*/
- void GetStateForDrawCall( int drawCallIndex );
+ void GetStateForDrawCall(int drawCallIndex);
/**
* Retrieves commands of specified type
*/
- std::vector<Command*> GetCommandsByType( CommandTypeMask mask );
-
+ std::vector<Command*> GetCommandsByType(CommandTypeMask mask);
private:
- TraceCallStack& mCallStack;
- TestGlAbstraction& mGlAbstraction;
+ TraceCallStack& mCallStack;
+ TestGlAbstraction& mGlAbstraction;
+
std::vector<Command> mCommands;
};
if(!value.empty())
{
// must be fixed
- for (auto &binding : value[0]->data.bindTextures.textureBindings)
+ for (auto& binding : value[0]->data.bindTextures.textureBindings)
{
- if (binding.texture)
+ if(binding.texture)
{
auto texture = Uncast<TestGraphicsTexture>(binding.texture);
texture->Bind(binding.binding);
- if (binding.sampler)
+ if(binding.sampler)
{
auto sampler = Uncast<TestGraphicsSampler>(binding.sampler);
- if (sampler)
+ if(sampler)
{
sampler->Apply(texture->GetTarget());
}
// IndexBuffer binding,
auto bindIndexBufferCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_INDEX_BUFFER);
- if (!bindIndexBufferCmds.empty())
+ if(!bindIndexBufferCmds.empty())
{
auto &indexBufferBinding = bindIndexBufferCmds[0]->data.bindIndexBuffer;
- if (indexBufferBinding.buffer)
+ if(indexBufferBinding.buffer)
{
auto buffer = Uncast<TestGraphicsBuffer>(indexBufferBinding.buffer);
buffer->Bind();
// VertexBuffer binding,
auto bindVertexBufferCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_VERTEX_BUFFERS);
- if (!bindVertexBufferCmds.empty())
+ if(!bindVertexBufferCmds.empty())
{
for (auto &binding : bindVertexBufferCmds[0]->data.bindVertexBuffers.vertexBufferBindings)
{
vertexBuffer->Bind();
}
}
+
+ bool scissorEnabled = false;
+
+ auto scissorTestList = commandBuffer->GetCommandsByType(0 | CommandType::SET_SCISSOR_TEST);
+ if(!scissorTestList.empty())
+ {
+ if(scissorTestList[0]->data.scissorTest.enable)
+ {
+ mGl.Enable(GL_SCISSOR_TEST);
+ scissorEnabled = true;
+ }
+ else
+ {
+ mGl.Disable(GL_SCISSOR_TEST);
+ }
+ }
+
+ auto scissorList = commandBuffer->GetCommandsByType(0 | CommandType::SET_SCISSOR);
+ if(!scissorList.empty() && scissorEnabled)
+ {
+ auto& rect = scissorList[0]->data.scissor.region;
+ mGl.Scissor(rect.x, rect.y, rect.width, rect.height);
+ }
+
+ auto viewportList = commandBuffer->GetCommandsByType(0 | CommandType::SET_VIEWPORT);
+ if(!viewportList.empty())
+ {
+ mGl.Viewport(viewportList[0]->data.viewport.region.x, viewportList[0]->data.viewport.region.y, viewportList[0]->data.viewport.region.width, viewportList[0]->data.viewport.region.height);
+ }
+
+ // ignore viewport enable
+
// Pipeline attribute setup
- auto bindPipelineCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_PIPELINE);
- if (!bindPipelineCmds.empty())
+ auto bindPipelineCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_PIPELINE);
+ if(!bindPipelineCmds.empty())
{
auto pipeline = bindPipelineCmds[0]->data.bindPipeline.pipeline;
- auto &vi = pipeline->vertexInputState;
- for (auto &attribute : vi.attributes)
+ auto& vi = pipeline->vertexInputState;
+ for(auto& attribute : vi.attributes)
{
mGl.EnableVertexAttribArray(attribute.location);
uint32_t attributeOffset = attribute.offset;
GetGlType(attribute.format),
GL_FALSE, // Not normalized
stride,
- reinterpret_cast<void *>(attributeOffset));
+ reinterpret_cast<void*>(attributeOffset));
}
+
// Cull face setup
- auto &rasterizationState = pipeline->rasterizationState;
- if (rasterizationState.cullMode == Graphics::CullMode::NONE)
+ auto& rasterizationState = pipeline->rasterizationState;
+ if(rasterizationState.cullMode == Graphics::CullMode::NONE)
{
mGl.Disable(GL_CULL_FACE);
}
// so it isn't present in the API (and won't have any tests!)
// Blending setup
- auto &colorBlendState = pipeline->colorBlendState;
- if (colorBlendState.blendEnable)
+ auto& colorBlendState = pipeline->colorBlendState;
+ if(colorBlendState.blendEnable)
{
mGl.Enable(GL_BLEND);
GetBlendFactor(colorBlendState.dstColorBlendFactor),
GetBlendFactor(colorBlendState.srcAlphaBlendFactor),
GetBlendFactor(colorBlendState.dstAlphaBlendFactor));
- if (colorBlendState.colorBlendOp != colorBlendState.alphaBlendOp)
+ if(colorBlendState.colorBlendOp != colorBlendState.alphaBlendOp)
{
mGl.BlendEquationSeparate(GetBlendOp(colorBlendState.colorBlendOp), GetBlendOp(colorBlendState.alphaBlendOp));
}
// UniformBuffer binding (once we know pipeline)
auto bindUniformBuffersCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_UNIFORM_BUFFER);
- if (!bindUniformBuffersCmds.empty())
+ if(!bindUniformBuffersCmds.empty())
{
auto buffer = bindUniformBuffersCmds[0]->data.bindUniformBuffers.standaloneUniformsBufferBinding;
// based on reflection, issue gl calls
- buffer.buffer->BindAsUniformBuffer( static_cast<const TestGraphicsProgram*>(pipeline->programState.program) );
+ buffer.buffer->BindAsUniformBuffer(static_cast<const TestGraphicsProgram*>(pipeline->programState.program));
}
- auto drawCmds = commandBuffer->GetCommandsByType( 0 |
- CommandType::DRAW |
- CommandType::DRAW_INDEXED_INDIRECT |
- CommandType::DRAW_INDEXED );
+ auto drawCmds = commandBuffer->GetCommandsByType(0 |
+ CommandType::DRAW |
+ CommandType::DRAW_INDEXED_INDIRECT |
+ CommandType::DRAW_INDEXED);
if(!drawCmds.empty())
{
}
}
// attribute clear
- for (auto &attribute : vi.attributes)
+ for(auto& attribute : vi.attributes)
{
mGl.DisableVertexAttribArray(attribute.location);
}
bool found = true;
for(auto& shader : *(programCreateInfo.shaderState))
{
- auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
- if(memcmp(cacheEntry.shaders[shader.pipelineStage], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize))
+ auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
+ std::vector<uint8_t> source;
+ source.resize(graphicsShader->mCreateInfo.sourceSize);
+ memcpy(&source[0], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize);
+
+ if(!std::equal(source.begin(), source.end(), cacheEntry.shaders[shader.pipelineStage].begin()))
{
found = false;
break;
mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats, mCustomUniforms);
for(auto& shader : *(programCreateInfo.shaderState))
{
- auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
- mProgramCache.back().shaders[shader.pipelineStage] = graphicsShader->mCreateInfo.sourceData;
+ auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
+ mProgramCache.back().shaders[shader.pipelineStage].resize(graphicsShader->mCreateInfo.sourceSize);
+ memcpy(&mProgramCache.back().shaders[shader.pipelineStage][0], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize);
}
return Graphics::MakeUnique<TestGraphicsProgram>(mProgramCache.back().programImpl);
}
struct ProgramCache
{
- std::map<Graphics::PipelineStage, const void*> shaders;
- TestGraphicsProgramImpl* programImpl;
+ std::map<Graphics::PipelineStage, std::vector<uint8_t>> shaders;
+ TestGraphicsProgramImpl* programImpl;
};
std::vector<ProgramCache> mProgramCache;
#include "test-graphics-shader.h"
#include <dali/public-api/object/property-map.h>
-#include <vector>
#include <string>
+#include <vector>
namespace Dali
{
namespace
{
static const std::vector<UniformData> UNIFORMS =
-{
- UniformData("uRendererColor",Property::Type::FLOAT),
- UniformData("uCustom", Property::Type::INTEGER),
- UniformData("uCustom3", Property::Type::VECTOR3),
- UniformData("uFadeColor", Property::Type::VECTOR4),
- UniformData("uUniform1", Property::Type::VECTOR4),
- UniformData("uUniform2", Property::Type::VECTOR4),
- UniformData("uUniform3", Property::Type::VECTOR4),
- UniformData("uFadeProgress", Property::Type::FLOAT),
- UniformData("uANormalMatrix", Property::Type::MATRIX3),
- UniformData("sEffect", Property::Type::FLOAT),
- UniformData("sTexture", Property::Type::FLOAT),
- UniformData("sTextureRect", Property::Type::FLOAT),
- UniformData("sGloss", Property::Type::FLOAT),
- UniformData("uColor", Property::Type::VECTOR4),
- UniformData("uModelMatrix", Property::Type::MATRIX),
- UniformData("uModelView", Property::Type::MATRIX),
- UniformData("uMvpMatrix", Property::Type::MATRIX),
- UniformData("uNormalMatrix", Property::Type::MATRIX3),
- UniformData("uProjection", Property::Type::MATRIX),
- UniformData("uSize", Property::Type::VECTOR3),
- UniformData("uViewMatrix", Property::Type::MATRIX),
- UniformData("uLightCameraProjectionMatrix", Property::Type::MATRIX),
- UniformData("uLightCameraViewMatrix", Property::Type::MATRIX),
+ {
+ UniformData("uRendererColor", Property::Type::FLOAT),
+ UniformData("uCustom", Property::Type::INTEGER),
+ UniformData("uCustom3", Property::Type::VECTOR3),
+ UniformData("uFadeColor", Property::Type::VECTOR4),
+ UniformData("uUniform1", Property::Type::VECTOR4),
+ UniformData("uUniform2", Property::Type::VECTOR4),
+ UniformData("uUniform3", Property::Type::VECTOR4),
+ UniformData("uFadeProgress", Property::Type::FLOAT),
+ UniformData("uANormalMatrix", Property::Type::MATRIX3),
+ UniformData("sEffect", Property::Type::FLOAT),
+ UniformData("sTexture", Property::Type::FLOAT),
+ UniformData("sTextureRect", Property::Type::FLOAT),
+ UniformData("sGloss", Property::Type::FLOAT),
+ UniformData("uColor", Property::Type::VECTOR4),
+ UniformData("uModelMatrix", Property::Type::MATRIX),
+ UniformData("uModelView", Property::Type::MATRIX),
+ UniformData("uMvpMatrix", Property::Type::MATRIX),
+ UniformData("uNormalMatrix", Property::Type::MATRIX3),
+ UniformData("uProjection", Property::Type::MATRIX),
+ UniformData("uSize", Property::Type::VECTOR3),
+ UniformData("uViewMatrix", Property::Type::MATRIX),
+ UniformData("uLightCameraProjectionMatrix", Property::Type::MATRIX),
+ UniformData("uLightCameraViewMatrix", Property::Type::MATRIX),
};
}
TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, Property::Array& vfs, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms)
- : mGl(gl),
- mCustomUniforms(customUniforms)
+: mGl(gl),
+ mCustomUniforms(customUniforms)
{
for(Property::Array::SizeType i = 0; i < vfs.Count(); ++i)
{
}
}
- mDefaultUniformBlock.name = "";
- mDefaultUniformBlock.members = {};
- mDefaultUniformBlock.binding = 0;
- mDefaultUniformBlock.size = 64 * (UNIFORMS.size() + mCustomUniforms.size());
+ mDefaultUniformBlock.name = "";
+ mDefaultUniformBlock.members = {};
+ mDefaultUniformBlock.binding = 0;
+ mDefaultUniformBlock.size = 64 * (UNIFORMS.size() + mCustomUniforms.size());
mDefaultUniformBlock.descriptorSet = 0;
mDefaultUniformBlock.members.clear();
int loc = 0;
- for( const auto& data : UNIFORMS )
+ for(const auto& data : UNIFORMS)
{
mDefaultUniformBlock.members.emplace_back();
- auto& item = mDefaultUniformBlock.members.back();
- item.name = data.name;
- item.binding = 0;
- item.offset = loc*64;
- item.location = loc++;
- item.bufferIndex = 0;
+ auto& item = mDefaultUniformBlock.members.back();
+ item.name = data.name;
+ item.binding = 0;
+ item.offset = loc * 64;
+ item.location = loc++;
+ item.bufferIndex = 0;
item.uniformClass = Graphics::UniformClass::UNIFORM;
}
- for( const auto& data : mCustomUniforms )
+ for(const auto& data : mCustomUniforms)
{
fprintf(stderr, "\ncustom uniforms: %s\n", data.name.c_str());
mDefaultUniformBlock.members.emplace_back();
- auto& item = mDefaultUniformBlock.members.back();
- item.name = data.name;
- item.binding = 0;
- item.offset = loc*64;
- item.location = loc++;
- item.bufferIndex = 0;
+ auto& item = mDefaultUniformBlock.members.back();
+ item.name = data.name;
+ item.binding = 0;
+ item.offset = loc * 64;
+ item.location = loc++;
+ item.bufferIndex = 0;
item.uniformClass = Graphics::UniformClass::UNIFORM;
}
return Graphics::ShaderLanguage::GLSL_3_1;
}
-Dali::Property::Type TestGraphicsReflection::GetMemberType( int blockIndex, int location) const
+Dali::Property::Type TestGraphicsReflection::GetMemberType(int blockIndex, int location) const
{
return location < static_cast<int>(UNIFORMS.size()) ? UNIFORMS[location].type : mCustomUniforms[location - UNIFORMS.size()].type;
}
* limitations under the License.
*/
-#include <dali/graphics-api/graphics-reflection.h>
#include <dali/graphics-api/graphics-program-create-info.h>
+#include <dali/graphics-api/graphics-reflection.h>
#include "test-gl-abstraction.h"
namespace Dali
{
-
class TestGraphicsReflection : public Graphics::Reflection
{
public:
}
}
- Dali::Property::Type GetMemberType( int blockIndex, int location) const;
+ Dali::Property::Type GetMemberType(int blockIndex, int location) const;
TestGlAbstraction& mGl;
mutable std::vector<std::string> mAttributes;
std::vector<UniformData> mCustomUniforms;
- Graphics::UniformBlockInfo mDefaultUniformBlock{}; ///< The emulated UBO containing all the standalone uniforms
- std::vector<Graphics::UniformBlockInfo> mUniformBlocks{}; ///< List of uniform blocks
+ Graphics::UniformBlockInfo mDefaultUniformBlock{}; ///< The emulated UBO containing all the standalone uniforms
+ std::vector<Graphics::UniformBlockInfo> mUniformBlocks{}; ///< List of uniform blocks
};
} // namespace Dali
DALI_TEST_CHECK(scissorTrace.FindMethodAndParams("Scissor", clipB));
DALI_TEST_CHECK(scissorTrace.FindMethodAndParams("Scissor", clipC));
DALI_TEST_CHECK(scissorTrace.FindMethodAndParams("Scissor", clipD));
- DALI_TEST_CHECK(scissorTrace.CountMethod("Scissor") == 4); // Scissor rect should not be changed in clippingActorE case. So count should be 4.
+ DALI_TEST_EQUALS(scissorTrace.CountMethod("Scissor"), 4, TEST_LOCATION); // Scissor rect should not be changed in clippingActorE case. So count should be 4.
END_TEST;
}
DALI_TEST_CHECK(graphicsCallstack.FindMethod("SubmitCommandBuffers"));
std::vector<Graphics::SubmitInfo>& submissions = graphics.mSubmitStack;
- DALI_TEST_EQUALS(submissions.size(), 1, TEST_LOCATION);
- DALI_TEST_EQUALS(submissions[0].cmdBuffer.size(), 1, TEST_LOCATION);
- TestGraphicsCommandBuffer* cmdBuf = static_cast<TestGraphicsCommandBuffer*>((submissions[0].cmdBuffer[0]));
- //auto pipeline = cmdBuf->mPipeline;
- auto result = cmdBuf->GetCommandsByType( 0 | CommandType::BIND_PIPELINE );
+ DALI_TEST_CHECK(submissions.size() > 0);
+
+ TestGraphicsCommandBuffer* cmdBuf = static_cast<TestGraphicsCommandBuffer*>((submissions.back().cmdBuffer[0]));
+
+ auto result = cmdBuf->GetCommandsByType(0 | CommandType::BIND_PIPELINE);
auto pipeline = result[0]->data.bindPipeline.pipeline;
if(pipeline)
/**
* @brief Changes scissor rect
*
- * @param[in] value 2D scissor area
+ * @param[in] value 2D scissor rectangle
*/
- virtual void SetScissor(Extent2D value) = 0;
+ virtual void SetScissor(Rect2D value) = 0;
/**
* @brief Enables/disables scissor test
} // Namespace Graphics
} // Namespace Dali
-#endif
\ No newline at end of file
+#endif
// Note: These MUST be in the same order as Dali::StencilOperation enum.
const int DaliStencilOperationToGL[] = {GL_ZERO, GL_KEEP, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT, GL_INCR_WRAP, GL_DECR_WRAP};
+inline Graphics::Viewport ViewportFromClippingBox(ClippingBox clippingBox, int orientation)
+{
+ Graphics::Viewport viewport{static_cast<float>(clippingBox.x), static_cast<float>(clippingBox.y), static_cast<float>(clippingBox.width), static_cast<float>(clippingBox.height), 0.0f, 0.0f};
+
+ if(orientation == 80 || orientation == 270)
+ {
+ viewport.width = static_cast<float>(clippingBox.height);
+ viewport.height = static_cast<float>(clippingBox.width);
+ }
+ return viewport;
+}
+
+inline Graphics::Rect2D RecalculateRect(Graphics::Rect2D rect, int orientation, Graphics::Viewport viewport)
+{
+ Graphics::Rect2D newRect;
+
+ // scissor's value should be set based on the default system coordinates.
+ // when the surface is rotated, the input valus already were set with the rotated angle.
+ // So, re-calculation is needed.
+ if(orientation == 90)
+ {
+ newRect.x = viewport.height - (rect.y + rect.height);
+ newRect.y = rect.x;
+ newRect.width = rect.height;
+ newRect.height = rect.width;
+ }
+ else if(orientation == 180)
+ {
+ newRect.x = viewport.width - (rect.x + rect.width);
+ newRect.y = viewport.height - (rect.y + rect.height);
+ newRect.width = rect.width;
+ newRect.height = rect.height;
+ }
+ else if(orientation == 270)
+ {
+ newRect.x = rect.y;
+ newRect.y = viewport.width - (rect.x + rect.width);
+ newRect.width = rect.height;
+ newRect.height = rect.width;
+ }
+ else
+ {
+ newRect.x = rect.x;
+ newRect.y = rect.y;
+ newRect.width = rect.width;
+ newRect.height = rect.height;
+ }
+ return newRect;
+}
+
+inline Graphics::Rect2D Rect2DFromClippingBox(ClippingBox clippingBox, int orientation, Graphics::Viewport viewport)
+{
+ Graphics::Rect2D rect2D{clippingBox.x, clippingBox.y, static_cast<uint32_t>(abs(clippingBox.width)), static_cast<uint32_t>(abs(clippingBox.height))};
+ return RecalculateRect(rect2D, orientation, viewport);
+}
+
+inline Graphics::Rect2D Rect2DFromRect(Dali::Rect<int> rect, int orientation, Graphics::Viewport viewport)
+{
+ Graphics::Rect2D rect2D{rect.x, rect.y, static_cast<uint32_t>(abs(rect.width)), static_cast<uint32_t>(abs(rect.height))};
+ return RecalculateRect(rect2D, orientation, viewport);
+}
+
/**
* @brief Find the intersection of two AABB rectangles.
* This is a logical AND operation. IE. The intersection is the area overlapped by both rectangles.
Integration::StencilBufferAvailable stencilBufferAvailable,
Vector<Graphics::Texture*>& boundTextures,
const RenderInstruction& instruction,
- const Rect<int>& rootClippingRect)
+ const Rect<int32_t>& viewport,
+ const Rect<int>& rootClippingRect,
+ int orientation)
{
DALI_PRINT_RENDER_LIST(renderList);
uint32_t lastClippingId(0u);
bool usedStencilBuffer(false);
bool firstDepthBufferUse(true);
- mViewportRectangle = context.GetViewport();
- mHasLayerScissor = false;
+
+ if(!mGraphicsCommandBuffer)
+ {
+ mGraphicsCommandBuffer = mGraphicsController.CreateCommandBuffer(
+ Graphics::CommandBufferCreateInfo()
+ .SetLevel(Graphics::CommandBufferLevel::SECONDARY),
+ nullptr);
+ }
+ else
+ {
+ mGraphicsCommandBuffer->Reset();
+ }
+
+ mViewportRectangle = viewport;
+ mGraphicsCommandBuffer->SetViewport(ViewportFromClippingBox(mViewportRectangle, orientation));
+ mHasLayerScissor = false;
// Setup Scissor testing (for both viewport and per-node scissor)
mScissorStack.clear();
- // Add root clipping rect (set manually for Render function ny partial update for example)
+ // Add root clipping rect (set manually for Render function by partial update for example)
// on the bottom of the stack
if(!rootClippingRect.IsEmpty())
{
- context.SetScissorTest(true);
- context.Scissor(rootClippingRect.x, rootClippingRect.y, rootClippingRect.width, rootClippingRect.height);
+ Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0);
+ mGraphicsCommandBuffer->SetScissorTestEnable(true);
+ mGraphicsCommandBuffer->SetScissor(Rect2DFromRect(rootClippingRect, orientation, graphicsViewport));
mScissorStack.push_back(rootClippingRect);
}
// We are not performing a layer clip and no clipping rect set. Add the viewport as the root scissor rectangle.
else if(!renderList.IsClipping())
{
- context.SetScissorTest(false);
+ mGraphicsCommandBuffer->SetScissorTestEnable(false);
mScissorStack.push_back(mViewportRectangle);
}
if(renderList.IsClipping())
{
- context.SetScissorTest(true);
+ Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0);
+ mGraphicsCommandBuffer->SetScissorTestEnable(true);
const ClippingBox& layerScissorBox = renderList.GetClippingBox();
- context.Scissor(layerScissorBox.x, layerScissorBox.y, layerScissorBox.width, layerScissorBox.height);
+ mGraphicsCommandBuffer->SetScissor(Rect2DFromClippingBox(layerScissorBox, orientation, graphicsViewport));
mScissorStack.push_back(layerScissorBox);
mHasLayerScissor = true;
}
+ // Submit scissor/viewport
+ Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH};
+ submitInfo.cmdBuffer.push_back(mGraphicsCommandBuffer.get());
+ mGraphicsController.SubmitCommandBuffers(submitInfo);
+
// 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)
{
}
}
-RenderAlgorithms::RenderAlgorithms()
-: mViewportRectangle(),
+RenderAlgorithms::RenderAlgorithms(Graphics::Controller& graphicsController)
+: mGraphicsController(graphicsController),
+ mViewportRectangle(),
mHasLayerScissor(false)
{
}
Integration::DepthBufferAvailable depthBufferAvailable,
Integration::StencilBufferAvailable stencilBufferAvailable,
Vector<Graphics::Texture*>& boundTextures,
- const Rect<int>& rootClippingRect)
+ const Rect<int32_t>& viewport,
+ const Rect<int>& rootClippingRect,
+ int orientation)
{
DALI_PRINT_RENDER_INSTRUCTION(instruction, bufferIndex);
stencilBufferAvailable,
boundTextures,
instruction, //added for reflection effect
- rootClippingRect);
+ viewport,
+ rootClippingRect,
+ orientation);
}
}
}
{
public:
/**
- * Constructor.
- */
- RenderAlgorithms();
+ * Constructor.
+ *
+ * @param[in] graphicsController The graphics controller
+ */
+ RenderAlgorithms(Graphics::Controller& graphicsController);
/**
- * Process a render-instruction.
- * @param[in] instruction The render-instruction to process.
- * @param[in] context The GL context.
- * @param[in] bufferIndex The current render buffer index (previous update buffer)
- * @param[in] depthBufferAvailable Whether the depth buffer is available
- * @param[in] stencilBufferAvailable Whether the stencil buffer is available
- * @param[in] boundTextures The textures bound for rendering
- */
+ * Process a render-instruction.
+ * @param[in] instruction The render-instruction to process.
+ * @param[in] context The GL context.
+ * @param[in] bufferIndex The current render buffer index (previous update buffer)
+ * @param[in] depthBufferAvailable Whether the depth buffer is available
+ * @param[in] stencilBufferAvailable Whether the stencil buffer is available
+ * @param[in] boundTextures The textures bound for rendering
+ * @param[in] viewport The viewport for drawing
+ * @param[in] rootClippingRect The clipping rectangle
+ * @param[in] orientation The surface orientation
+ */
void ProcessRenderInstruction(const SceneGraph::RenderInstruction& instruction,
Context& context,
BufferIndex bufferIndex,
Integration::DepthBufferAvailable depthBufferAvailable,
Integration::StencilBufferAvailable stencilBufferAvailable,
Vector<Graphics::Texture*>& boundTextures,
- const Rect<int>& rootClippingRect);
+ const Rect<int32_t>& viewport,
+ const Rect<int>& rootClippingRect,
+ int orientation);
private:
/**
- * @brief Calculate a 2D AABB (axis aligned bounding box) in screen space.
- * The RenderItems dimensions are translated and a Z value of 0 is assumed for this purpose.
- * No projection is performed, but rotation on Z is supported.
- * @param[in] item The RenderItem to generate an AABB for
- * @return The generated AABB in screen space
- */
+ * @brief Calculate a 2D AABB (axis aligned bounding box) in screen space.
+ * The RenderItems dimensions are translated and a Z value of 0 is assumed for this purpose.
+ * No projection is performed, but rotation on Z is supported.
+ * @param[in] item The RenderItem to generate an AABB for
+ * @return The generated AABB in screen space
+ */
inline Dali::ClippingBox CalculateScreenSpaceAABB(const Dali::Internal::SceneGraph::RenderItem& item);
/**
- * @brief Perform any scissor clipping related operations based on the current RenderItem.
- * This includes:
- * - Determining if any action is to be taken (so the method can be exited early if not).
- * - If the node is a clipping node, apply the nodes clip intersected with the current/parent scissor clip.
- * - If we have gone up the scissor hierarchy, and need to un-apply a scissor clip.
- * - Disable scissor clipping completely if it is not needed
- * @param[in] item The current RenderItem (about to be rendered)
- * @param[in] context The current Context
- * @param[in] instruction The render-instruction to process.
- */
+ * @brief Perform any scissor clipping related operations based on the current RenderItem.
+ * This includes:
+ * - Determining if any action is to be taken (so the method can be exited early if not).
+ * - If the node is a clipping node, apply the nodes clip intersected with the current/parent scissor clip.
+ * - If we have gone up the scissor hierarchy, and need to un-apply a scissor clip.
+ * - Disable scissor clipping completely if it is not needed
+ * @param[in] item The current RenderItem (about to be rendered)
+ * @param[in] context The current Context
+ * @param[in] instruction The render-instruction to process.
+ */
inline void SetupScissorClipping(const Dali::Internal::SceneGraph::RenderItem& item, Context& context, const Dali::Internal::SceneGraph::RenderInstruction& instruction);
/**
- * @brief Set up the clipping based on the specified clipping settings.
- * @param[in] item The current RenderItem (about to be rendered)
- * @param[in] context The context
- * @param[in/out] usedStencilBuffer True if the stencil buffer has been used so far within this RenderList. Used by StencilMode::ON.
- * @param[in/out] lastClippingDepth The stencil depth of the last renderer drawn. Used by the clipping feature.
- * @param[in/out] lastClippingId The clipping ID of the last renderer drawn. Used by the clipping feature.
- * @param[in] stencilBufferAvailable Whether the stencil buffer is available
- * @param[in] instruction The render-instruction to process.
- */
+ * @brief Set up the clipping based on the specified clipping settings.
+ * @param[in] item The current RenderItem (about to be rendered)
+ * @param[in] context The context
+ * @param[in/out] usedStencilBuffer True if the stencil buffer has been used so far within this RenderList. Used by StencilMode::ON.
+ * @param[in/out] lastClippingDepth The stencil depth of the last renderer drawn. Used by the clipping feature.
+ * @param[in/out] lastClippingId The clipping ID of the last renderer drawn. Used by the clipping feature.
+ * @param[in] stencilBufferAvailable Whether the stencil buffer is available
+ * @param[in] instruction The render-instruction to process.
+ */
inline void SetupClipping(const Dali::Internal::SceneGraph::RenderItem& item,
Context& context,
bool& usedStencilBuffer,
const Dali::Internal::SceneGraph::RenderInstruction& instruction);
/**
- * @brief Process a render-list.
- * @param[in] renderList The render-list to process.
- * @param[in] context The GL context.
- * @param[in] buffer The current render buffer index (previous update buffer)
- * @param[in] viewMatrix The view matrix from the appropriate camera.
- * @param[in] projectionMatrix The projection matrix from the appropriate camera.
- * @param[in] depthBufferAvailable Whether the depth buffer is available
- * @param[in] stencilBufferAvailable Whether the stencil buffer is available
- * @param[in] boundTextures The textures bound for rendering
- */
+ * @brief Process a render-list.
+ * @param[in] renderList The render-list to process.
+ * @param[in] context The GL context.
+ * @param[in] buffer The current render buffer index (previous update buffer)
+ * @param[in] viewMatrix The view matrix from the appropriate camera.
+ * @param[in] projectionMatrix The projection matrix from the appropriate camera.
+ * @param[in] depthBufferAvailable Whether the depth buffer is available
+ * @param[in] stencilBufferAvailable Whether the stencil buffer is available
+ * @param[in] boundTextures The textures bound for rendering
+ * @param[in] viewport The Viewport
+ * @param[in] rootClippingRect The root clipping rectangle
+ * @param[in] orientation The Scene's surface orientation
+ */
inline void ProcessRenderList(const Dali::Internal::SceneGraph::RenderList& renderList,
Context& context,
BufferIndex bufferIndex,
Integration::StencilBufferAvailable stencilBufferAvailable,
Vector<Graphics::Texture*>& boundTextures,
const Dali::Internal::SceneGraph::RenderInstruction& instruction, // in the case of reflection, things like CullFace need to be adjusted for reflection world
- const Rect<int>& rootClippingRect);
+ const Rect<int32_t>& viewport,
+ const Rect<int>& rootClippingRect,
+ int orientation);
// Prevent copying:
RenderAlgorithms(RenderAlgorithms& rhs);
using ScissorStackType = std::vector<Dali::ClippingBox>; ///< The container type used to maintain the applied scissor hierarchy
+ Graphics::Controller& mGraphicsController;
+ Graphics::UniquePtr<Graphics::CommandBuffer> mGraphicsCommandBuffer{};
+
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
currentContext(&context),
graphicsController(graphicsController),
renderQueue(),
- renderAlgorithms(),
+ renderAlgorithms(graphicsController),
frameCount(0u),
renderBufferIndex(SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX),
rendererContainer(),
mImpl->currentContext->BindFramebuffer(GL_FRAMEBUFFER, 0u);
}
+ // @todo Should this be a command in it's own right?
if(!instruction.mFrameBuffer)
{
mImpl->currentContext->Viewport(surfaceRect.x,
// Set surface orientation
mImpl->currentContext->SetSurfaceOrientation(surfaceOrientation);
+ /*** Clear region of framebuffer or surface before drawing ***/
+
bool clearFullFrameRect = true;
if(instruction.mFrameBuffer != nullptr)
{
clearFullFrameRect = false;
}
+ // @todo The following block should be a command in it's own right.
+ // Currently takes account of surface orientation in Context.
mImpl->currentContext->Viewport(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height);
-
if(instruction.mIsClearColorSet)
{
mImpl->currentContext->ClearColor(clearColor.r,
depthBufferAvailable,
stencilBufferAvailable,
mImpl->boundTextures,
- clippingRect);
+ viewportRect,
+ clippingRect,
+ surfaceOrientation);
// Synchronise the FBO/Texture access when there are multiple contexts
if(mImpl->currentContext->IsSurfacelessContextSupported())