Gfx Shader support 85/254185/8
authorAdam Bialogonski <adam.b@samsung.com>
Thu, 25 Feb 2021 17:03:53 +0000 (17:03 +0000)
committeradam.b <adam.b@samsung.com>
Fri, 26 Feb 2021 23:22:58 +0000 (23:22 +0000)
Change-Id: Iad029d20494b801eccd20eb7148b52234e7a3d2f

automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp
automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h
dali/graphics-api/graphics-controller.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h
dali/internal/render/renderers/shader-cache.cpp
dali/internal/render/renderers/shader-cache.h
dali/internal/render/shaders/program.cpp
dali/internal/render/shaders/program.h

index 23f98ba..9913886 100644 (file)
@@ -789,4 +789,10 @@ bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0,
   return false;
 }
 
+bool TestGraphicsController::GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData )
+{
+  mCallStack.PushCall("GetProgramParameter", "");
+  return false;
+}
+
 } // namespace Dali
index c235d29..9179a39 100644 (file)
@@ -303,6 +303,18 @@ public: // Test Functions
     mSubmitStack.clear();
   }
 
+  /**
+   * @brief Retrieves program parameters
+   *
+   * This function can be used to retrieve data from internal implementation
+   *
+   * @param[in] program Valid program object
+   * @param[in] parameterId Integer parameter id
+   * @param[out] outData Pointer to output memory
+   * @return True on success
+   */
+  bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData ) override;
+
 public:
   mutable TraceCallStack                    mCallStack;
   mutable TraceCallStack                    mCommandBufferCallStack;
index 9732ab1..e375acd 100644 (file)
@@ -342,6 +342,18 @@ public:
    */
   virtual bool PipelineEquals(const Pipeline& pipeline0, const Pipeline& pipeline1) const = 0;
 
+  /**
+   * @brief Retrieves program parameters
+   *
+   * This function can be used to retrieve data from internal implementation
+   *
+   * @param[in] program Valid program object
+   * @param[in] parameterId Integer parameter id
+   * @param[out] outData Pointer to output memory
+   * @return True on success
+   */
+  virtual bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData ) = 0;
+
 protected:
   /**
    * Creates controller
index 671accd..cac206d 100644 (file)
@@ -723,17 +723,6 @@ void Renderer::Render(Context&                                             conte
     return;
   }
 
-  // Get the program to use
-  // The program cache owns the Program object so we don't need to worry about this raw allocation here.
-  ShaderDataPtr shaderData = mRenderDataProvider->GetShader().GetShaderData();
-  Program*      program    = Program::New(*mProgramCache, shaderData, (shaderData->GetHints() & Dali::Shader::Hint::MODIFIES_GEOMETRY) != 0x0);
-
-  if(!program)
-  {
-    DALI_LOG_ERROR("Failed to get program for shader at address %p.\n", reinterpret_cast<void*>(&mRenderDataProvider->GetShader()));
-    return;
-  }
-
   Graphics::UniquePtr<Graphics::CommandBuffer> commandBuffer = mGraphicsController->CreateCommandBuffer(
     Graphics::CommandBufferCreateInfo()
       .SetLevel(Graphics::CommandBufferLevel::SECONDARY),
@@ -747,8 +736,9 @@ void Renderer::Render(Context&                                             conte
 
   // Create Shader.
   // Really, need to have a pipeline cache in implementation.
-
-  mLegacyProgram.programId = program->GetProgramId();
+  // Get the program to use
+  // The program cache owns the Program object so we don't need to worry about this raw allocation here.
+  ShaderDataPtr shaderData = mRenderDataProvider->GetShader().GetShaderData();
 
   Dali::Graphics::Shader& vertexShader = mShaderCache->GetShader(
     shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::VERTEX_SHADER),
@@ -761,16 +751,32 @@ void Renderer::Render(Context&                                             conte
     shaderData->GetSourceMode());
 
   std::vector<Graphics::ShaderState> shaderStates{
-    Graphics::ShaderState().SetShader(vertexShader).SetPipelineStage(Graphics::PipelineStage::VERTEX_SHADER),
-    Graphics::ShaderState().SetShader(fragmentShader).SetPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER)};
+    Graphics::ShaderState()
+      .SetShader(vertexShader)
+      .SetPipelineStage(Graphics::PipelineStage::VERTEX_SHADER),
+    Graphics::ShaderState()
+      .SetShader(fragmentShader)
+      .SetPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER)};
+
   auto createInfo = Graphics::ProgramCreateInfo();
   createInfo.SetShaderState(shaderStates);
 
-  mGraphicsProgram = mGraphicsController->CreateProgram(createInfo, nullptr);
+  mGraphicsProgram = mGraphicsController->CreateProgram(createInfo, std::move(mGraphicsProgram));
+  Program* program = Program::New(*mProgramCache,
+                                  shaderData,
+                                  *mGraphicsController,
+                                  *mGraphicsProgram,
+                                  (shaderData->GetHints() & Dali::Shader::Hint::MODIFIES_GEOMETRY) != 0x0);
+
+  if(!program)
+  {
+    DALI_LOG_ERROR("Failed to get program for shader at address %p.\n", reinterpret_cast<void*>(&mRenderDataProvider->GetShader()));
+    return;
+  }
 
   // Temporarily create a pipeline here - this will be used for transporting
   // topology, vertex format, attrs, rasterization state
-  mGraphicsPipeline = std::move(PrepareGraphicsPipeline(*program, instruction, blend));
+  mGraphicsPipeline = PrepareGraphicsPipeline(*program, instruction, blend, std::move(mGraphicsPipeline));
 
   commandBuffer->BindPipeline(*mGraphicsPipeline.get());
 
@@ -891,7 +897,8 @@ bool Renderer::Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvid
 Graphics::UniquePtr<Graphics::Pipeline> Renderer::PrepareGraphicsPipeline(
   Program&                                             program,
   const Dali::Internal::SceneGraph::RenderInstruction& instruction,
-  bool                                                 blend)
+  bool                                                 blend,
+  Graphics::UniquePtr<Graphics::Pipeline>&&            oldPipeline)
 {
   Graphics::InputAssemblyState inputAssemblyState{};
   Graphics::VertexInputState   vertexInputState{};
@@ -1057,7 +1064,7 @@ Graphics::UniquePtr<Graphics::Pipeline> Renderer::PrepareGraphicsPipeline(
       .SetColorBlendState(&colorBlendState)
       .SetProgramState(&programState)
       .SetNextExtension(&mLegacyProgram),
-    nullptr);
+    std::move(oldPipeline));
 }
 
 } // namespace Render
index 10fe621..a629e11 100644 (file)
@@ -453,7 +453,8 @@ private:
   Graphics::UniquePtr<Graphics::Pipeline> PrepareGraphicsPipeline(
     Program&                                             program,
     const Dali::Internal::SceneGraph::RenderInstruction& instruction,
-    bool                                                 blend);
+    bool                                                 blend,
+    Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline);
 
 private:
   Graphics::Controller*                        mGraphicsController;
index 9b9468e..2a86735 100644 (file)
@@ -51,11 +51,6 @@ Dali::Graphics::Shader& ShaderCache::GetShader(const std::vector<char> shaderCod
   return *retval;
 }
 
-void ShaderCache::DestroyGraphicsObjects()
-{
-  mItems.clear();
-}
-
 } // namespace Render
 } // namespace Internal
 } // namespace Dali
index ec06d63..b041c28 100644 (file)
@@ -75,11 +75,6 @@ struct ShaderCache
    */
   Dali::Graphics::Shader& GetShader(const std::vector<char> shaderCode, Graphics::PipelineStage stage, Graphics::ShaderSourceMode type);
 
-  /**
-   * Destroy any graphics objects owned by this scene graph object
-   */
-  void DestroyGraphicsObjects();
-
 private:
   std::vector<Item>           mItems;
   Dali::Graphics::Controller& mController;
index 3d25e01..725974c 100644 (file)
@@ -32,7 +32,8 @@
 #include <dali/public-api/common/constants.h>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/common/dali-vector.h>
-
+#include <dali/graphics-api/graphics-program.h>
+#include <dali/graphics-api/graphics-controller.h>
 namespace
 {
 void LogWithLineNumbers(const char* source)
@@ -99,22 +100,29 @@ const char* const gStdUniforms[Program::UNIFORM_TYPE_LAST] =
 
 // IMPLEMENTATION
 
-Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool modifiesGeometry)
+Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::Program& gfxProgram, bool modifiesGeometry)
 {
-  size_t   shaderHash = shaderData->GetHashValue();
+  uint32_t programId{0u};
+
+  // Get program id and use it as hash for the cache
+  // in order to maintain current functionality as long as needed
+  gfxController.GetProgramParameter( gfxProgram, 1, &programId );
+
+  size_t   shaderHash = programId;
+
   Program* program    = cache.GetProgram(shaderHash);
 
   if(nullptr == program)
   {
     // program not found so create it
-    program = new Program(cache, shaderData, modifiesGeometry);
+    program = new Program(cache, shaderData, programId, modifiesGeometry);
     program->Load();
     cache.AddProgram(shaderHash, program);
   }
-
   return program;
 }
 
+
 void Program::Use()
 {
   if(mLinked)
@@ -624,7 +632,7 @@ bool Program::ModifiesGeometry()
   return mModifiesGeometry;
 }
 
-Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool modifiesGeometry)
+Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, uint32_t programId, bool modifiesGeometry)
 : mCache(cache),
   mGlAbstraction(mCache.GetGlAbstraction()),
   mProjectionMatrix(nullptr),
@@ -653,6 +661,9 @@ Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool m
 
   // reset values
   ResetAttribsUniformCache();
+
+  mProgramId = programId;
+  mLinked = true;
 }
 
 Program::~Program()
@@ -662,6 +673,13 @@ Program::~Program()
 
 void Program::Load()
 {
+  // Temporary, exist if program id is already set
+  if(mProgramId)
+  {
+    GetActiveSamplerUniforms();
+    return;
+  }
+
   DALI_ASSERT_ALWAYS(nullptr != mProgramData.Get() && "Program data is not initialized");
   DALI_ASSERT_DEBUG(mProgramId == 0 && "mProgramId != 0, so about to leak a GL resource by overwriting it.");
 
@@ -749,6 +767,11 @@ void Program::Load()
 
 void Program::Unload()
 {
+  // Bypass when using gfx program
+  if(!mProgramData && mProgramId)
+  {
+    return;
+  }
   FreeShaders();
 
   if(this == mCache.GetCurrentProgram())
@@ -770,6 +793,11 @@ void Program::Unload()
 
 bool Program::CompileShader(GLenum shaderType, GLuint& shaderId, const char* src)
 {
+  // Bypass when using gfx program
+  if(!mProgramData && mProgramId)
+  {
+    return true;
+  }
   if(!shaderId)
   {
     LOG_GL("CreateShader(%d)\n", shaderType);
@@ -811,6 +839,11 @@ bool Program::CompileShader(GLenum shaderType, GLuint& shaderId, const char* src
 
 void Program::Link()
 {
+  // Bypass when using gfx program
+  if(!mProgramData && mProgramId)
+  {
+    return;
+  }
   LOG_GL("LinkProgram(%d)\n", mProgramId);
   CHECK_GL(mGlAbstraction, mGlAbstraction.LinkProgram(mProgramId));
 
@@ -840,6 +873,11 @@ void Program::Link()
 
 void Program::FreeShaders()
 {
+  // Bypass when using gfx program
+  if(!mProgramData && mProgramId)
+  {
+    return;
+  }
   if(mVertexShaderId)
   {
     LOG_GL("DeleteShader(%d)\n", mVertexShaderId);
index db0c399..9a801d8 100644 (file)
 
 namespace Dali
 {
+namespace Graphics
+{
+class Controller;
+class Program;
+}
 class Matrix;
 
 namespace Integration
@@ -102,10 +107,12 @@ public:
    * @param[in] shaderData  A pointer to a data structure containing the program source
    *                        and optionally precompiled binary. If the binary is empty the program bytecode
    *                        is copied into it after compilation and linking)
+   * param[in]  gfxController Reference to valid graphics Controller object
+   * param[in]  gfxProgram Reference to vali graphics Program object
    * @param[in] modifiesGeometry True if the shader modifies geometry
    * @return pointer to the program
    */
-  static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool modifiesGeometry);
+  static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::Program& gfxProgram, bool modifiesGeometry);
 
   /**
    * Takes this program into use
@@ -311,9 +318,10 @@ private: // Implementation
    * Constructor, private so no direct instantiation
    * @param[in] cache where the programs are stored
    * @param[in] shaderData A smart pointer to a data structure containing the program source and binary
+   * @param[in] programId A GL program id
    * @param[in] modifiesGeometry True if the vertex shader changes geometry
    */
-  Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool modifiesGeometry);
+  Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, uint32_t programId, bool modifiesGeometry);
 
 public:
   /**