}
mProgramCache.emplace_back();
- mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats, mCustomUniforms, mCustomUniformBlocks);
+ mProgramCache.back().programImpl = new TestGraphicsProgramImpl(*this, mGl, programCreateInfo, mVertexFormats, mCustomUniforms, mCustomUniformBlocks);
for(auto& shader : *(programCreateInfo.shaderState))
{
Graphics::UniquePtr<Graphics::Texture> ReleaseTextureFromResourceId(uint32_t resourceId) override;
public: // Test Functions
+ void SetAutoAttrCreation(bool v)
+ {
+ mAutoAttrCreation = v;
+ }
+ bool AutoAttrCreation()
+ {
+ return mAutoAttrCreation;
+ }
+
void SetVertexFormats(Property::Array& vfs)
{
mVertexFormats = vfs;
TestGraphicsSyncImplementation mGraphicsSyncImpl;
TestGlContextHelperAbstraction mGlContextHelperAbstraction;
- bool isDiscardQueueEmptyResult{true};
- bool isDrawOnResumeRequiredResult{true};
-
+ bool isDiscardQueueEmptyResult{true};
+ bool isDrawOnResumeRequiredResult{true};
+ bool mAutoAttrCreation{true};
Property::Array mVertexFormats;
struct ProgramCache
namespace Dali
{
-TestGraphicsProgramImpl::TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks)
-: mGl(gl),
+TestGraphicsProgramImpl::TestGraphicsProgramImpl(TestGraphicsController& controller, TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks)
+: mController(controller),
+ mGl(gl),
mId(gl.CreateProgram()),
mCreateInfo(createInfo),
- mReflection(gl, mId, vertexFormats, createInfo, customUniforms, customUniformBlocks)
+ mReflection(controller, gl, mId, vertexFormats, createInfo, customUniforms, customUniformBlocks)
{
// Ensure active sampler uniforms are set
mGl.SetCustomUniforms(customUniforms);
namespace Dali
{
+class TestGraphicsController;
+
class TestGraphicsProgramImpl
{
public:
- TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks);
+ TestGraphicsProgramImpl(TestGraphicsController& controller, TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks);
// For API
const TestGraphicsReflection& GetReflection() const
bool GetParameter(uint32_t parameterId, void* outData);
public:
+ TestGraphicsController& mController;
TestGlAbstraction& mGl;
uint32_t mId;
Graphics::ProgramCreateInfo mCreateInfo;
*/
#include "test-graphics-reflection.h"
+#include "test-graphics-controller.h"
#include "test-graphics-shader.h"
#include <dali/public-api/object/property-map.h>
} // namespace
-TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, uint32_t programId, Property::Array& vfs, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks)
-: mGl(gl),
+TestGraphicsReflection::TestGraphicsReflection(TestGraphicsController& controller, TestGlAbstraction& gl, uint32_t programId, Property::Array& vfs, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks)
+: mController(controller),
+ mGl(gl),
mCustomUniforms(customUniforms)
{
for(Property::Array::SizeType i = 0; i < vfs.Count(); ++i)
uint32_t TestGraphicsReflection::GetVertexAttributeLocation(const std::string& name) const
{
- // Automatically assign locations to named attributes when requested
auto iter = std::find(mAttributes.begin(), mAttributes.end(), name);
if(iter != mAttributes.end())
{
return iter - mAttributes.begin();
}
- else
+ else if(mController.AutoAttrCreation())
{
uint32_t location = mAttributes.size();
mAttributes.push_back(name);
return location;
}
- return 0u;
+
+ return -1;
}
Dali::Graphics::VertexInputAttributeFormat TestGraphicsReflection::GetVertexAttributeFormat(uint32_t location) const
namespace Dali
{
+class TestGraphicsController;
+
class TestGraphicsReflection : public Graphics::Reflection
{
public:
class TestUniformBlockInfo;
- TestGraphicsReflection(TestGlAbstraction& gl, uint32_t program_id, Property::Array& vertexFormats, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms, std::vector<TestUniformBlockInfo>& customUniformBlocks);
+ TestGraphicsReflection(TestGraphicsController& controller, TestGlAbstraction& gl, uint32_t program_id, Property::Array& vertexFormats, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms, std::vector<TestUniformBlockInfo>& customUniformBlocks);
uint32_t GetVertexAttributeLocation(const std::string& name) const override;
Dali::Graphics::VertexInputAttributeFormat GetVertexAttributeFormat(uint32_t location) const override;
return mUniformBlocks[index];
}
+ TestGraphicsController& mController;
TestGlAbstraction& mGl;
mutable std::vector<std::string> mAttributes;
std::vector<UniformData> mCustomUniforms;
*
*/
+#define DEBUG_ENABLED 1
+
// EXTERNAL INCLUDES
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/devel-api/common/capabilities.h>
END_TEST;
}
+int UtcDaliRendererPreparePipelineMissingAttrs(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test that rendering an actor tries to bind the attributes locs from the reflection, but fails");
+ Debug::Filter::SetGlobalLogLevel(Debug::Verbose);
+
+ Property::Map modelVF;
+ modelVF["aPosition"] = Property::VECTOR3;
+ modelVF["aNormal"] = Property::VECTOR3;
+ Property::Array vfs;
+ vfs.PushBack(modelVF);
+
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.SetAutoAttrCreation(false);
+ graphics.SetVertexFormats(vfs);
+
+ Property::Map vf = CreateModelVertexFormat();
+ Geometry modelGeometry = CreateModelGeometry(vf);
+ Shader shader = Shader::New("vertexSrc", "fragmentSrc");
+ Renderer renderer = Renderer::New(modelGeometry, shader);
+ Actor actor = Actor::New();
+
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ application.GetScene().Add(actor);
+
+ TraceCallStack& cmdBufCallstack = graphics.mCommandBufferCallStack;
+ TraceCallStack& graphicsCallstack = graphics.mCallStack;
+ cmdBufCallstack.Enable(true);
+ graphicsCallstack.Enable(true);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(graphicsCallstack.FindMethod("SubmitCommandBuffers"));
+ std::vector<Graphics::SubmitInfo>& submissions = graphics.mSubmitStack;
+ DALI_TEST_CHECK(submissions.size() > 0);
+
+ TestGraphicsCommandBuffer* cmdBuf = static_cast<TestGraphicsCommandBuffer*>((submissions.back().cmdBuffer[0]));
+
+ auto result = cmdBuf->GetChildCommandsByType(0 | CommandType::BIND_PIPELINE);
+ auto pipeline = result[0]->data.bindPipeline.pipeline;
+
+ if(pipeline)
+ {
+ DALI_TEST_EQUALS(pipeline->vertexInputState.attributes.size(), 2, TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
int UtcDaliRendererUniformArrayOfStruct(void)
{
TestApplication application;
/**
* Provides unfiltered logging for global warning level messages
*/
-#define DALI_LOG_WARNING(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::WARNING, "%s " format, ASSERT_LOCATION, ##__VA_ARGS__)
+#define DALI_LOG_WARNING(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::WARNING, format, ##__VA_ARGS__)
#else // DEBUG_ENABLED
targetstoPresent.emplace_back(currentRenderTarget);
- // reset the program matrices for all programs once per frame
- // this ensures we will set view and projection matrix once per program per camera
- mImpl->programController.ResetProgramMatrices();
-
if(!instruction.mIgnoreRenderToFbo && (instruction.mFrameBuffer != nullptr))
{
// Offscreen buffer rendering
// Flush UBOs
mImpl->uniformBufferManager->Flush(sceneObject, renderToFbo);
-
mImpl->renderAlgorithms.SubmitCommandBuffer();
mImpl->commandBufferSubmitted = true;
namespace Internal
{
-class ProgramCache;
class ShaderSaver;
namespace Render
{
namespace
{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_PIPELINE_CACHE");
+#endif
+
constexpr uint32_t CACHE_CLEAN_FRAME_COUNT = 600; // 60fps * 10sec
// Helper to get the vertex input format
Graphics::VertexInputState vertexInputState{};
uint32_t base = 0;
+ bool attrNotFound = false;
for(auto&& vertexBuffer : geometry->GetVertexBuffers())
{
const VertexBuffer::Format& vertexFormat = *vertexBuffer->GetFormat();
}
else
{
+ attrNotFound = true;
DALI_LOG_WARNING("Attribute not found in the shader: %s\n", attributeName.GetCString());
// Don't bind unused attributes.
}
level0.inputState = vertexInputState;
it = level0nodes.insert(level0nodes.end(), std::move(level0));
+
+ if(attrNotFound)
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::General,
+ "!!!!!!! Attributes not found. !!!!!!!!\n"
+ "Shader src: VERT:\n%s\nFRAGMENT:\n%s\n",
+ program->GetShaderData()->GetVertexShader(),
+ program->GetShaderData()->GetFragmentShader());
+ }
}
return it;
ProgramController::~ProgramController() = default;
-void ProgramController::ResetProgramMatrices()
-{
- const ProgramIterator end = mProgramCache.End();
- for(ProgramIterator iter = mProgramCache.Begin(); iter != end; ++iter)
- {
- Program* program = (*iter)->GetProgram();
- program->SetProjectionMatrix(nullptr);
- program->SetViewMatrix(nullptr);
- }
-}
-
void ProgramController::ResetReferenceCount()
{
for(auto&& item : mProgramCache)
void ProgramController::AddProgram(size_t shaderHash, Program* program)
{
- // we expect unique hash values so it is event thread side's job to guarantee that
+ // we expect unique hash values so it is caller's job to guarantee that
// AddProgram is only called after program checks that GetProgram returns NULL
mProgramCache.PushBack(new ProgramPair(program, shaderHash));
}
class ShaderSaver;
/**
- * This class is the owner of shader programs
+ * This class ensures that only unique programs are created.
*/
class ProgramController : public ProgramCache
{
public: // API
/**
- * Resets the program matrices. Must be called at the beginning of every frame
- */
- void ResetProgramMatrices();
-
- /**
* @brief Reset all program reference count as 0.
*/
void ResetReferenceCount();
{
// program not found so create it
program = new Program(cache, shaderData, gfxController);
- DALI_LOG_RELEASE_INFO("Program::New() created a unique program\n");
+
+ DALI_LOG_INFO(Debug::Filter::gShader, Debug::Verbose, "Program::New() created a unique program:\n VertexShader:\n%s\n\n FragShader:\n%s\n", shaderData->GetVertexShader(), shaderData->GetFragmentShader());
cache.AddProgram(shaderHash, program);
}
Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& controller)
: mCache(cache),
- mProjectionMatrix(nullptr),
- mViewMatrix(nullptr),
mGfxProgram(nullptr),
mGfxController(controller),
mProgramData(std::move(shaderData))
*/
static Program* New(ProgramCache& cache, const Internal::ShaderDataPtr& shaderData, Graphics::Controller& gfxController);
- /**
- * Set the projection matrix that has currently been sent
- * @param matrix to set
- */
- void SetProjectionMatrix(const Matrix* matrix)
- {
- mProjectionMatrix = matrix;
- }
-
- /**
- * Get the projection matrix that has currently been sent
- * @return the matrix that is set
- */
- const Matrix* GetProjectionMatrix()
- {
- return mProjectionMatrix;
- }
-
- /**
- * Set the projection matrix that has currently been sent
- * @param matrix to set
- */
- void SetViewMatrix(const Matrix* matrix)
+ Internal::ShaderDataPtr GetShaderData()
{
- mViewMatrix = matrix;
- }
-
- /**
- * Get the projection matrix that has currently been sent
- * @return the matrix that is set
- */
- const Matrix* GetViewMatrix()
- {
- return mViewMatrix;
+ return mProgramData;
}
[[nodiscard]] Graphics::Program& GetGraphicsProgram() const
return mUniformBlockMemoryRequirements;
}
-private: // Data
- ProgramCache& mCache; ///< The program cache
- const Matrix* mProjectionMatrix; ///< currently set projection matrix
- const Matrix* mViewMatrix; ///< currently set view matrix
-
+private: // Data
+ ProgramCache& mCache; ///< The program cache
Graphics::UniquePtr<Graphics::Program> mGfxProgram; ///< Gfx program
Graphics::Controller& mGfxController; /// < Gfx controller
Internal::ShaderDataPtr mProgramData; ///< Shader program source and binary (when compiled & linked or loaded)
namespace Internal
{
class Program;
-class ProgramCache;
namespace SceneGraph
{