Adding Depth/Stencil implementation 71/257571/2
authorDavid Steele <david.steele@samsung.com>
Tue, 27 Apr 2021 15:02:16 +0000 (16:02 +0100)
committerDavid Steele <david.steele@samsung.com>
Wed, 28 Apr 2021 12:05:21 +0000 (13:05 +0100)
Ensures depth and stencil masks are set before clearing
at the start of the render pass.

Change-Id: Iec81fc4bf07d2a79b0a09b684fbbf477f9b57155

automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.h
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.cpp
dali/internal/graphics/gles-impl/gles-context.cpp
dali/internal/graphics/gles-impl/gles-context.h
dali/internal/graphics/gles-impl/gles-graphics-command-buffer.cpp
dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h
dali/internal/graphics/gles-impl/gles-graphics-render-pass.cpp
dali/internal/graphics/gles-impl/gles-graphics-types.h

index e34b852..9f86b99 100644 (file)
 
 namespace Dali
 {
+std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op)
+{
+  switch(op)
+  {
+    case Graphics::StencilOp::KEEP:
+      os << "KEEP";
+      return os;
+    case Graphics::StencilOp::ZERO:
+      os << "ZERO";
+      return os;
+    case Graphics::StencilOp::REPLACE:
+      os << "REPLACE";
+      return os;
+    case Graphics::StencilOp::INCREMENT_AND_CLAMP:
+      os << "INCREMENT_AND_CLAMP";
+      return os;
+    case Graphics::StencilOp::DECREMENT_AND_CLAMP:
+      os << "DECREMENT_AND_CLAMP";
+      return os;
+    case Graphics::StencilOp::INVERT:
+      os << "INVERT";
+      return os;
+    case Graphics::StencilOp::INCREMENT_AND_WRAP:
+      os << "INCREMENT_AND_WRAP";
+      return os;
+    case Graphics::StencilOp::DECREMENT_AND_WRAP:
+      os << "DECREMENT_AND_WRAP";
+      return os;
+  }
+  return os;
+};
+
+std::ostream& operator<<(std::ostream& os, Graphics::CompareOp op)
+{
+  switch(op)
+  {
+    case Graphics::CompareOp::NEVER:
+      os << "NEVER";
+      return os;
+    case Graphics::CompareOp::LESS:
+      os << "LESS";
+      return os;
+    case Graphics::CompareOp::EQUAL:
+      os << "EQUAL";
+      return os;
+    case Graphics::CompareOp::LESS_OR_EQUAL:
+      os << "LESS_OR_EQUAL";
+      return os;
+    case Graphics::CompareOp::GREATER:
+      os << "GREATER";
+      return os;
+    case Graphics::CompareOp::NOT_EQUAL:
+      os << "NOT_EQUAL";
+      return os;
+    case Graphics::CompareOp::GREATER_OR_EQUAL:
+      os << "GREATER_OR_EQUAL";
+      return os;
+    case Graphics::CompareOp::ALWAYS:
+      os << "ALWAYS";
+      return os;
+  }
+  return os;
+};
+
 TestGraphicsCommandBuffer::TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction)
 : mCallStack(callstack),
   mGlAbstraction(glAbstraction)
index a68cb7f..b75a402 100644 (file)
@@ -54,9 +54,23 @@ enum class CommandType
   SET_VIEWPORT_TEST       = 1 << 13,
   BEGIN_RENDER_PASS       = 1 << 14,
   END_RENDER_PASS         = 1 << 15,
-  EXECUTE_COMMAND_BUFFERS = 1 << 16
+  EXECUTE_COMMAND_BUFFERS = 1 << 16,
+  SET_COLOR_MASK          = 1 << 17,
+  CLEAR_STENCIL_BUFFER    = 1 << 18,
+  CLEAR_DEPTH_BUFFER      = 1 << 19,
+  SET_STENCIL_TEST_ENABLE = 1 << 20,
+  SET_STENCIL_WRITE_MASK  = 1 << 21,
+  SET_STENCIL_OP          = 1 << 22,
+  SET_STENCIL_FUNC        = 1 << 23,
+  SET_DEPTH_COMPARE_OP    = 1 << 24,
+  SET_DEPTH_TEST_ENABLE   = 1 << 25,
+  SET_DEPTH_WRITE_ENABLE  = 1 << 26,
 };
 
+std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op);
+
+std::ostream& operator<<(std::ostream& os, Graphics::CompareOp op);
+
 using CommandTypeMask = uint32_t;
 template<typename T>
 inline CommandTypeMask operator|(T flags, CommandType bit)
@@ -294,6 +308,59 @@ struct Command
         data.viewportTest.enable = rhs.data.viewportTest.enable;
         break;
       }
+      case CommandType::SET_COLOR_MASK:
+      {
+        data.colorMask.enabled = rhs.data.colorMask.enabled;
+        break;
+      }
+      case CommandType::CLEAR_STENCIL_BUFFER:
+      {
+        break;
+      }
+      case CommandType::CLEAR_DEPTH_BUFFER:
+      {
+        break;
+      }
+      case CommandType::SET_STENCIL_TEST_ENABLE:
+      {
+        data.stencilTest.enabled = rhs.data.stencilTest.enabled;
+        break;
+      }
+      case CommandType::SET_STENCIL_FUNC:
+      {
+        data.stencilFunc.compareMask = rhs.data.stencilFunc.compareMask;
+        data.stencilFunc.compareOp   = rhs.data.stencilFunc.compareOp;
+        data.stencilFunc.reference   = rhs.data.stencilFunc.reference;
+        break;
+      }
+      case CommandType::SET_STENCIL_WRITE_MASK:
+      {
+        data.stencilWriteMask.mask = rhs.data.stencilWriteMask.mask;
+        break;
+      }
+      case CommandType::SET_STENCIL_OP:
+      {
+        data.stencilOp.failOp      = rhs.data.stencilOp.failOp;
+        data.stencilOp.depthFailOp = rhs.data.stencilOp.depthFailOp;
+        data.stencilOp.passOp      = rhs.data.stencilOp.passOp;
+        break;
+      }
+
+      case CommandType::SET_DEPTH_COMPARE_OP:
+      {
+        data.depth.compareOp = rhs.data.depth.compareOp;
+        break;
+      }
+      case CommandType::SET_DEPTH_TEST_ENABLE:
+      {
+        data.depth.testEnabled = rhs.data.depth.testEnabled;
+        break;
+      }
+      case CommandType::SET_DEPTH_WRITE_ENABLE:
+      {
+        data.depth.writeEnabled = rhs.data.depth.writeEnabled;
+        break;
+      }
     }
     type = rhs.type;
   }
@@ -394,6 +461,59 @@ struct Command
         data.viewportTest.enable = rhs.data.viewportTest.enable;
         break;
       }
+
+      case CommandType::SET_COLOR_MASK:
+      {
+        data.colorMask.enabled = rhs.data.colorMask.enabled;
+        break;
+      }
+      case CommandType::CLEAR_STENCIL_BUFFER:
+      {
+        break;
+      }
+      case CommandType::CLEAR_DEPTH_BUFFER:
+      {
+        break;
+      }
+      case CommandType::SET_STENCIL_TEST_ENABLE:
+      {
+        data.stencilTest.enabled = rhs.data.stencilTest.enabled;
+        break;
+      }
+      case CommandType::SET_STENCIL_WRITE_MASK:
+      {
+        data.stencilWriteMask.mask = rhs.data.stencilWriteMask.mask;
+        break;
+      }
+      case CommandType::SET_STENCIL_OP:
+      {
+        data.stencilOp.failOp      = rhs.data.stencilOp.failOp;
+        data.stencilOp.depthFailOp = rhs.data.stencilOp.depthFailOp;
+        data.stencilOp.passOp      = rhs.data.stencilOp.passOp;
+        break;
+      }
+      case CommandType::SET_STENCIL_FUNC:
+      {
+        data.stencilFunc.compareMask = rhs.data.stencilFunc.compareMask;
+        data.stencilFunc.compareOp   = rhs.data.stencilFunc.compareOp;
+        data.stencilFunc.reference   = rhs.data.stencilFunc.reference;
+        break;
+      }
+      case CommandType::SET_DEPTH_COMPARE_OP:
+      {
+        data.depth.compareOp = rhs.data.depth.compareOp;
+        break;
+      }
+      case CommandType::SET_DEPTH_TEST_ENABLE:
+      {
+        data.depth.testEnabled = rhs.data.depth.testEnabled;
+        break;
+      }
+      case CommandType::SET_DEPTH_WRITE_ENABLE:
+      {
+        data.depth.writeEnabled = rhs.data.depth.writeEnabled;
+        break;
+      }
     }
     type = rhs.type;
   }
@@ -480,6 +600,41 @@ struct Command
       std::vector<const TestGraphicsCommandBuffer*> buffers;
     } executeCommandBuffers;
 
+    struct
+    {
+      Graphics::CompareOp compareOp;
+      bool                testEnabled;
+      bool                writeEnabled;
+    } depth;
+
+    struct
+    {
+      Graphics::StencilOp failOp;
+      Graphics::StencilOp passOp;
+      Graphics::StencilOp depthFailOp;
+    } stencilOp;
+
+    struct
+    {
+      uint32_t mask;
+    } stencilWriteMask;
+
+    struct
+    {
+      uint32_t            compareMask;
+      Graphics::CompareOp compareOp;
+      uint32_t            reference;
+    } stencilFunc;
+
+    struct
+    {
+      bool enabled;
+    } stencilTest;
+
+    struct
+    {
+      bool enabled;
+    } colorMask;
   } data;
 };
 
@@ -748,6 +903,112 @@ public:
     mCommands.back().data.viewportTest.enable = value;
   }
 
+  void SetColorMask(bool enabled) override
+  {
+    TraceCallStack::NamedParams params;
+    params["enabled"] << (enabled ? "T" : "F");
+    mCallStack.PushCall("SetColorMask", params.str(), params);
+    mCommands.emplace_back();
+    mCommands.back().type                   = CommandType::SET_COLOR_MASK;
+    mCommands.back().data.colorMask.enabled = enabled;
+  }
+
+  void ClearStencilBuffer() override
+  {
+    mCallStack.PushCall("SetStencilMask", "");
+    mCommands.emplace_back();
+    mCommands.back().type = CommandType::CLEAR_STENCIL_BUFFER;
+  }
+
+  void SetStencilTestEnable(bool stencilEnable) override
+  {
+    TraceCallStack::NamedParams params;
+    params["enabled"] << (stencilEnable ? "T" : "F");
+    mCallStack.PushCall("SetStencilTestEnable", params.str(), params);
+    mCommands.emplace_back();
+    mCommands.back().type                     = CommandType::SET_STENCIL_TEST_ENABLE;
+    mCommands.back().data.stencilTest.enabled = stencilEnable;
+  }
+
+  void SetStencilWriteMask(uint32_t writeMask) override
+  {
+    TraceCallStack::NamedParams params;
+    params["writeMask"] << std::hex << writeMask;
+    mCallStack.PushCall("SetStencilWriteMask", params.str(), params);
+    mCommands.emplace_back();
+    mCommands.back().type                       = CommandType::SET_STENCIL_WRITE_MASK;
+    mCommands.back().data.stencilWriteMask.mask = writeMask;
+  }
+
+  void SetStencilOp(Graphics::StencilOp failOp,
+                    Graphics::StencilOp passOp,
+                    Graphics::StencilOp depthFailOp) override
+  {
+    TraceCallStack::NamedParams params;
+    params["failOp"] << failOp;
+    params["passOp"] << passOp;
+    params["depthFailOp"] << depthFailOp;
+    mCallStack.PushCall("SetStencilOp", params.str(), params);
+    mCommands.emplace_back();
+    mCommands.back().type                       = CommandType::SET_STENCIL_OP;
+    mCommands.back().data.stencilOp.failOp      = failOp;
+    mCommands.back().data.stencilOp.passOp      = passOp;
+    mCommands.back().data.stencilOp.depthFailOp = depthFailOp;
+  }
+
+  void SetStencilFunc(Graphics::CompareOp compareOp,
+                      uint32_t            reference,
+                      uint32_t            compareMask) override
+  {
+    TraceCallStack::NamedParams params;
+    params["compareOp"] << compareOp;
+    params["compareMask"] << std::hex << compareMask;
+    params["reference"] << std::hex << reference;
+    mCallStack.PushCall("SetStencilFunc", params.str(), params);
+
+    mCommands.emplace_back();
+    mCommands.back().type = CommandType::SET_STENCIL_FUNC;
+
+    mCommands.back().data.stencilFunc.compareOp   = compareOp;
+    mCommands.back().data.stencilFunc.compareMask = compareMask;
+    mCommands.back().data.stencilFunc.reference   = reference;
+  }
+
+  void SetDepthCompareOp(Graphics::CompareOp compareOp) override
+  {
+    TraceCallStack::NamedParams params;
+    params["compareOp"] << compareOp;
+    mCallStack.PushCall("SetDepthCompareOp", params.str(), params);
+    mCommands.emplace_back();
+    mCommands.back().type                 = CommandType::SET_DEPTH_COMPARE_OP;
+    mCommands.back().data.depth.compareOp = compareOp;
+  }
+
+  void SetDepthTestEnable(bool depthTestEnable) override
+  {
+    TraceCallStack::NamedParams params;
+    params["enabled"] << (depthTestEnable ? "T" : "F");
+    mCallStack.PushCall("SetDepthTestEnable", params.str(), params);
+    mCommands.emplace_back();
+    mCommands.back().type                   = CommandType::SET_DEPTH_TEST_ENABLE;
+    mCommands.back().data.depth.testEnabled = depthTestEnable;
+  }
+  void SetDepthWriteEnable(bool depthWriteEnable) override
+  {
+    TraceCallStack::NamedParams params;
+    params["enabled"] << (depthWriteEnable ? "T" : "F");
+    mCallStack.PushCall("SetDepthWriteEnable", params.str(), params);
+    mCommands.emplace_back();
+    mCommands.back().type                    = CommandType::SET_DEPTH_WRITE_ENABLE;
+    mCommands.back().data.depth.writeEnabled = depthWriteEnable;
+  }
+  void ClearDepthBuffer() override
+  {
+    mCallStack.PushCall("ClearDepthBuffer", "");
+    mCommands.emplace_back();
+    mCommands.back().type = CommandType::CLEAR_DEPTH_BUFFER;
+  }
+
   [[nodiscard]] const std::vector<Command>& GetCommands() const
   {
     return mCommands;
index ddcf0f5..a3a0fee 100644 (file)
@@ -384,6 +384,76 @@ GLenum GetBlendOp(Graphics::BlendOp blendOp)
   return op;
 }
 
+struct GLCompareOp
+{
+  constexpr explicit GLCompareOp(Graphics::CompareOp compareOp)
+  {
+    switch(compareOp)
+    {
+      case Graphics::CompareOp::NEVER:
+        op = GL_NEVER;
+        break;
+      case Graphics::CompareOp::LESS:
+        op = GL_LESS;
+        break;
+      case Graphics::CompareOp::EQUAL:
+        op = GL_EQUAL;
+        break;
+      case Graphics::CompareOp::LESS_OR_EQUAL:
+        op = GL_LEQUAL;
+        break;
+      case Graphics::CompareOp::GREATER:
+        op = GL_GREATER;
+        break;
+      case Graphics::CompareOp::NOT_EQUAL:
+        op = GL_NOTEQUAL;
+        break;
+      case Graphics::CompareOp::GREATER_OR_EQUAL:
+        op = GL_GEQUAL;
+        break;
+      case Graphics::CompareOp::ALWAYS:
+        op = GL_ALWAYS;
+        break;
+    }
+  }
+  GLenum op{GL_LESS};
+};
+
+struct GLStencilOp
+{
+  constexpr explicit GLStencilOp(Graphics::StencilOp stencilOp)
+  {
+    switch(stencilOp)
+    {
+      case Graphics::StencilOp::KEEP:
+        op = GL_KEEP;
+        break;
+      case Graphics::StencilOp::ZERO:
+        op = GL_ZERO;
+        break;
+      case Graphics::StencilOp::REPLACE:
+        op = GL_REPLACE;
+        break;
+      case Graphics::StencilOp::INCREMENT_AND_CLAMP:
+        op = GL_INCR;
+        break;
+      case Graphics::StencilOp::DECREMENT_AND_CLAMP:
+        op = GL_DECR;
+        break;
+      case Graphics::StencilOp::INVERT:
+        op = GL_INVERT;
+        break;
+      case Graphics::StencilOp::INCREMENT_AND_WRAP:
+        op = GL_INCR_WRAP;
+        break;
+      case Graphics::StencilOp::DECREMENT_AND_WRAP:
+        op = GL_DECR_WRAP;
+        break;
+    }
+  }
+  GLenum op{GL_KEEP};
+};
+
 class TestGraphicsMemory : public Graphics::Memory
 {
 public:
@@ -602,6 +672,82 @@ void TestGraphicsController::ProcessCommandBuffer(TestGraphicsCommandBuffer& com
         mGl.Viewport(rect.x, rect.y, rect.width, rect.height);
         break;
       }
+
+      case CommandType::SET_COLOR_MASK:
+      {
+        // Set all channels to the same mask
+        const bool mask = cmd.data.colorMask.enabled;
+        mGl.ColorMask(mask, mask, mask, mask);
+        break;
+      }
+      case CommandType::CLEAR_STENCIL_BUFFER:
+      {
+        mGl.Clear(GL_STENCIL_BUFFER_BIT);
+        break;
+      }
+      case CommandType::CLEAR_DEPTH_BUFFER:
+      {
+        mGl.Clear(GL_DEPTH_BUFFER_BIT);
+        break;
+      }
+
+      case CommandType::SET_STENCIL_TEST_ENABLE:
+      {
+        if(cmd.data.stencilTest.enabled)
+        {
+          mGl.Enable(GL_STENCIL_TEST);
+        }
+        else
+        {
+          mGl.Disable(GL_STENCIL_TEST);
+        }
+        break;
+      }
+
+      case CommandType::SET_STENCIL_FUNC:
+      {
+        mGl.StencilFunc(GLCompareOp(cmd.data.stencilFunc.compareOp).op,
+                        cmd.data.stencilFunc.reference,
+                        cmd.data.stencilFunc.compareMask);
+        break;
+      }
+
+      case CommandType::SET_STENCIL_WRITE_MASK:
+      {
+        mGl.StencilMask(cmd.data.stencilWriteMask.mask);
+        break;
+      }
+      case CommandType::SET_STENCIL_OP:
+      {
+        mGl.StencilOp(GLStencilOp(cmd.data.stencilOp.failOp).op,
+                      GLStencilOp(cmd.data.stencilOp.depthFailOp).op,
+                      GLStencilOp(cmd.data.stencilOp.passOp).op);
+        break;
+      }
+
+      case CommandType::SET_DEPTH_COMPARE_OP:
+      {
+        mGl.DepthFunc(GLCompareOp(cmd.data.depth.compareOp).op);
+        break;
+      }
+      case CommandType::SET_DEPTH_TEST_ENABLE:
+      {
+        if(cmd.data.depth.testEnabled)
+        {
+          mGl.Enable(GL_DEPTH_TEST);
+        }
+        else
+        {
+          mGl.Disable(GL_DEPTH_TEST);
+        }
+        break;
+      }
+      case CommandType::SET_DEPTH_WRITE_ENABLE:
+      {
+        mGl.DepthMask(cmd.data.depth.writeEnabled);
+        break;
+      }
+
       case CommandType::EXECUTE_COMMAND_BUFFERS:
       {
         // Process secondary command buffers
@@ -663,10 +809,24 @@ void TestGraphicsController::ProcessCommandBuffer(TestGraphicsCommandBuffer& com
               const auto& depthStencil = renderPass->attachments.back();
               if(depthStencil.loadOp == Graphics::AttachmentLoadOp::CLEAR)
               {
+                mGl.DepthMask(true);
+                uint32_t depthClearColor = 0u;
+                if(clearValues.size() == renderPass->attachments.size())
+                {
+                  depthClearColor = clearValues.back().depthStencil.depth;
+                }
+                mGl.ClearDepthf(depthClearColor);
                 mask |= GL_DEPTH_BUFFER_BIT;
               }
               if(depthStencil.stencilLoadOp == Graphics::AttachmentLoadOp::CLEAR)
               {
+                uint32_t stencilClearColor = 0u;
+                if(clearValues.size() == renderPass->attachments.size())
+                {
+                  stencilClearColor = clearValues.back().depthStencil.stencil;
+                }
+                mGl.ClearStencil(stencilClearColor);
+                mGl.StencilMask(0xFF); // Clear all the bitplanes (assume 8)
                 mask |= GL_STENCIL_BUFFER_BIT;
               }
             }
index dec07de..910cce5 100644 (file)
@@ -416,6 +416,67 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm
         mGlAbstraction->Viewport(cmd.viewport.region.x, cmd.viewport.region.y, cmd.viewport.region.width, cmd.viewport.region.height);
         break;
       }
+
+      case GLES::CommandType::SET_COLOR_MASK:
+      {
+        mCurrentContext->ColorMask(cmd.colorMask.enabled);
+        break;
+      }
+      case GLES::CommandType::CLEAR_STENCIL_BUFFER:
+      {
+        mCurrentContext->ClearStencilBuffer();
+        break;
+      }
+      case GLES::CommandType::CLEAR_DEPTH_BUFFER:
+      {
+        mCurrentContext->ClearDepthBuffer();
+        break;
+      }
+
+      case GLES::CommandType::SET_STENCIL_TEST_ENABLE:
+      {
+        mCurrentContext->SetStencilTestEnable(cmd.stencilTest.enabled);
+        break;
+      }
+
+      case GLES::CommandType::SET_STENCIL_FUNC:
+      {
+        mCurrentContext->StencilFunc(cmd.stencilFunc.compareOp,
+                                     cmd.stencilFunc.reference,
+                                     cmd.stencilFunc.compareMask);
+        break;
+      }
+
+      case GLES::CommandType::SET_STENCIL_WRITE_MASK:
+      {
+        mCurrentContext->StencilMask(cmd.stencilWriteMask.mask);
+        break;
+      }
+
+      case GLES::CommandType::SET_STENCIL_OP:
+      {
+        mCurrentContext->StencilOp(cmd.stencilOp.failOp,
+                                   cmd.stencilOp.depthFailOp,
+                                   cmd.stencilOp.passOp);
+        break;
+      }
+
+      case GLES::CommandType::SET_DEPTH_COMPARE_OP:
+      {
+        mCurrentContext->SetDepthCompareOp(cmd.depth.compareOp);
+        break;
+      }
+      case GLES::CommandType::SET_DEPTH_TEST_ENABLE:
+      {
+        mCurrentContext->SetDepthTestEnable(cmd.depth.testEnabled);
+        break;
+      }
+      case GLES::CommandType::SET_DEPTH_WRITE_ENABLE:
+      {
+        mCurrentContext->SetDepthWriteEnable(cmd.depth.writeEnabled);
+        break;
+      }
+
       case GLES::CommandType::BEGIN_RENDERPASS:
       {
         auto&       renderTarget = *cmd.beginRenderPass.renderTarget;
index 8618730..7d04067 100644 (file)
@@ -431,8 +431,7 @@ void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin)
 
   const auto& targetInfo = renderTarget.GetCreateInfo();
 
-  auto& gl       = *mImpl->mController.GetGL();
-  auto& graphics = *mImpl->mController.GetGraphicsInterface();
+  auto& gl = *mImpl->mController.GetGL();
 
   if(targetInfo.surface)
   {
@@ -473,10 +472,12 @@ void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin)
     const auto& depthStencil = attachments.back();
     if(depthStencil.loadOp == AttachmentLoadOp::CLEAR)
     {
+      gl.DepthMask(true);
       mask |= GL_DEPTH_BUFFER_BIT;
     }
     if(depthStencil.stencilLoadOp == AttachmentLoadOp::CLEAR)
     {
+      gl.StencilMask(0xFF);
       mask |= GL_STENCIL_BUFFER_BIT;
     }
   }
@@ -507,4 +508,82 @@ void Context::ClearState()
   mImpl->mCurrentTextureBindings.clear();
 }
 
+void Context::ColorMask(bool enabled)
+{
+  auto& gl = *mImpl->mController.GetGL();
+  gl.ColorMask(enabled, enabled, enabled, enabled);
+}
+
+void Context::ClearStencilBuffer()
+{
+  auto& gl = *mImpl->mController.GetGL();
+  gl.Clear(GL_STENCIL_BUFFER_BIT);
+}
+
+void Context::ClearDepthBuffer()
+{
+  auto& gl = *mImpl->mController.GetGL();
+  gl.Clear(GL_DEPTH_BUFFER_BIT);
+}
+
+void Context::SetStencilTestEnable(bool stencilEnable)
+{
+  auto& gl = *mImpl->mController.GetGL();
+  if(stencilEnable)
+  {
+    gl.Enable(GL_STENCIL_TEST);
+  }
+  else
+  {
+    gl.Disable(GL_STENCIL_TEST);
+  }
+}
+
+void Context::StencilMask(uint32_t writeMask)
+{
+  auto& gl = *mImpl->mController.GetGL();
+  gl.StencilMask(writeMask);
+}
+
+void Context::StencilFunc(Graphics::CompareOp compareOp,
+                          uint32_t            reference,
+                          uint32_t            compareMask)
+{
+  auto& gl = *mImpl->mController.GetGL();
+  gl.StencilFunc(GLCompareOp(compareOp).op, reference, compareMask);
+}
+
+void Context::StencilOp(Graphics::StencilOp failOp,
+                        Graphics::StencilOp depthFailOp,
+                        Graphics::StencilOp passOp)
+{
+  auto& gl = *mImpl->mController.GetGL();
+  gl.StencilOp(GLStencilOp(failOp).op, GLStencilOp(depthFailOp).op, GLStencilOp(passOp).op);
+}
+
+void Context::SetDepthCompareOp(Graphics::CompareOp compareOp)
+{
+  auto& gl = *mImpl->mController.GetGL();
+  gl.DepthFunc(GLCompareOp(compareOp).op);
+}
+
+void Context::SetDepthTestEnable(bool depthTestEnable)
+{
+  auto& gl = *mImpl->mController.GetGL();
+  if(depthTestEnable)
+  {
+    gl.Enable(GL_DEPTH_TEST);
+  }
+  else
+  {
+    gl.Disable(GL_DEPTH_TEST);
+  }
+}
+
+void Context::SetDepthWriteEnable(bool depthWriteEnable)
+{
+  auto& gl = *mImpl->mController.GetGL();
+  gl.DepthMask(depthWriteEnable);
+}
+
 } // namespace Dali::Graphics::GLES
index 2c09adf..c9df90f 100644 (file)
@@ -137,6 +137,21 @@ public:
    */
   void EndRenderPass();
 
+  void ColorMask(bool enabled);
+  void ClearStencilBuffer();
+  void ClearDepthBuffer();
+  void SetStencilTestEnable(bool stencilEnable);
+  void StencilMask(uint32_t writeMask);
+  void StencilFunc(Graphics::CompareOp compareOp,
+                   uint32_t            reference,
+                   uint32_t            compareMask);
+  void StencilOp(Graphics::StencilOp failOp,
+                 Graphics::StencilOp depthFailOp,
+                 Graphics::StencilOp passOp);
+  void SetDepthCompareOp(Graphics::CompareOp compareOp);
+  void SetDepthTestEnable(bool depthTestEnable);
+  void SetDepthWriteEnable(bool depthWriteEnable);
+
 private:
   /**
    * @brief Clear current state
index 83f010e..59169db 100644 (file)
@@ -228,6 +228,74 @@ void CommandBuffer::SetViewportEnable(bool value)
   // There is no GL equivalent
 }
 
+void CommandBuffer::SetColorMask(bool enabled)
+{
+  mCommands.emplace_back(CommandType::SET_COLOR_MASK);
+  auto& cmd = mCommands.back().colorMask;
+  ;
+  cmd.enabled = enabled;
+}
+
+void CommandBuffer::ClearStencilBuffer()
+{
+  mCommands.emplace_back(CommandType::CLEAR_STENCIL_BUFFER);
+}
+
+void CommandBuffer::SetStencilTestEnable(bool stencilEnable)
+{
+  mCommands.emplace_back(CommandType::SET_STENCIL_TEST_ENABLE);
+  mCommands.back().stencilTest.enabled = stencilEnable;
+}
+
+void CommandBuffer::SetStencilWriteMask(uint32_t writeMask)
+{
+  mCommands.emplace_back(CommandType::SET_STENCIL_WRITE_MASK);
+  mCommands.back().stencilWriteMask.mask = writeMask;
+}
+
+void CommandBuffer::SetStencilOp(Graphics::StencilOp failOp,
+                                 Graphics::StencilOp passOp,
+                                 Graphics::StencilOp depthFailOp)
+{
+  mCommands.emplace_back(CommandType::SET_STENCIL_OP);
+  auto& cmd       = mCommands.back().stencilOp;
+  cmd.failOp      = failOp;
+  cmd.passOp      = passOp;
+  cmd.depthFailOp = depthFailOp;
+}
+
+void CommandBuffer::SetStencilFunc(Graphics::CompareOp compareOp,
+                                   uint32_t            reference,
+                                   uint32_t            compareMask)
+{
+  mCommands.emplace_back(CommandType::SET_STENCIL_FUNC);
+  auto& cmd       = mCommands.back().stencilFunc;
+  cmd.compareOp   = compareOp;
+  cmd.compareMask = compareMask;
+  cmd.reference   = reference;
+}
+
+void CommandBuffer::SetDepthCompareOp(Graphics::CompareOp compareOp)
+{
+  mCommands.emplace_back(CommandType::SET_DEPTH_COMPARE_OP);
+  mCommands.back().depth.compareOp = compareOp;
+}
+
+void CommandBuffer::SetDepthTestEnable(bool depthTestEnable)
+{
+  mCommands.emplace_back(CommandType::SET_DEPTH_TEST_ENABLE);
+  mCommands.back().depth.testEnabled = depthTestEnable;
+}
+void CommandBuffer::SetDepthWriteEnable(bool depthWriteEnable)
+{
+  mCommands.emplace_back(CommandType::SET_DEPTH_WRITE_ENABLE);
+  mCommands.back().depth.writeEnabled = depthWriteEnable;
+}
+void CommandBuffer::ClearDepthBuffer()
+{
+  mCommands.emplace_back(CommandType::CLEAR_DEPTH_BUFFER);
+}
+
 void CommandBuffer::PresentRenderTarget(GLES::RenderTarget* renderTarget)
 {
   mCommands.emplace_back(CommandType::PRESENT_RENDER_TARGET);
index 214f19c..9eb0db1 100644 (file)
@@ -52,6 +52,16 @@ enum class CommandType
   END_RENDERPASS,
   EXECUTE_COMMAND_BUFFERS,
   PRESENT_RENDER_TARGET,
+  SET_COLOR_MASK,
+  CLEAR_STENCIL_BUFFER,
+  CLEAR_DEPTH_BUFFER,
+  SET_STENCIL_TEST_ENABLE,
+  SET_STENCIL_WRITE_MASK,
+  SET_STENCIL_OP,
+  SET_STENCIL_FUNC,
+  SET_DEPTH_COMPARE_OP,
+  SET_DEPTH_TEST_ENABLE,
+  SET_DEPTH_WRITE_ENABLE,
 };
 
 /**
@@ -220,12 +230,65 @@ struct Command
         presentRenderTarget = rhs.presentRenderTarget;
         break;
       }
+      case CommandType::SET_COLOR_MASK:
+      {
+        colorMask.enabled = rhs.colorMask.enabled;
+        break;
+      }
+      case CommandType::CLEAR_STENCIL_BUFFER:
+      {
+        break;
+      }
+      case CommandType::CLEAR_DEPTH_BUFFER:
+      {
+        break;
+      }
+      case CommandType::SET_STENCIL_TEST_ENABLE:
+      {
+        stencilTest.enabled = rhs.stencilTest.enabled;
+        break;
+      }
+      case CommandType::SET_STENCIL_FUNC:
+      {
+        stencilFunc.compareMask = rhs.stencilFunc.compareMask;
+        stencilFunc.compareOp   = rhs.stencilFunc.compareOp;
+        stencilFunc.reference   = rhs.stencilFunc.reference;
+        break;
+      }
+      case CommandType::SET_STENCIL_WRITE_MASK:
+      {
+        stencilWriteMask.mask = rhs.stencilWriteMask.mask;
+        break;
+      }
+      case CommandType::SET_STENCIL_OP:
+      {
+        stencilOp.failOp      = rhs.stencilOp.failOp;
+        stencilOp.depthFailOp = rhs.stencilOp.depthFailOp;
+        stencilOp.passOp      = rhs.stencilOp.passOp;
+        break;
+      }
+
+      case CommandType::SET_DEPTH_COMPARE_OP:
+      {
+        depth.compareOp = rhs.depth.compareOp;
+        break;
+      }
+      case CommandType::SET_DEPTH_TEST_ENABLE:
+      {
+        depth.testEnabled = rhs.depth.testEnabled;
+        break;
+      }
+      case CommandType::SET_DEPTH_WRITE_ENABLE:
+      {
+        depth.writeEnabled = rhs.depth.writeEnabled;
+        break;
+      }
     }
     type = rhs.type;
   }
 
   /**
-   * @brief Copy constructor
+   * @brief Move constructor
    * @param[in] rhs Command
    */
   Command(Command&& rhs) noexcept
@@ -321,6 +384,59 @@ struct Command
         presentRenderTarget = rhs.presentRenderTarget;
         break;
       }
+      case CommandType::SET_COLOR_MASK:
+      {
+        colorMask.enabled = rhs.colorMask.enabled;
+        break;
+      }
+      case CommandType::CLEAR_STENCIL_BUFFER:
+      {
+        break;
+      }
+      case CommandType::CLEAR_DEPTH_BUFFER:
+      {
+        break;
+      }
+      case CommandType::SET_STENCIL_TEST_ENABLE:
+      {
+        stencilTest.enabled = rhs.stencilTest.enabled;
+        break;
+      }
+      case CommandType::SET_STENCIL_FUNC:
+      {
+        stencilFunc.compareMask = rhs.stencilFunc.compareMask;
+        stencilFunc.compareOp   = rhs.stencilFunc.compareOp;
+        stencilFunc.reference   = rhs.stencilFunc.reference;
+        break;
+      }
+      case CommandType::SET_STENCIL_WRITE_MASK:
+      {
+        stencilWriteMask.mask = rhs.stencilWriteMask.mask;
+        break;
+      }
+      case CommandType::SET_STENCIL_OP:
+      {
+        stencilOp.failOp      = rhs.stencilOp.failOp;
+        stencilOp.depthFailOp = rhs.stencilOp.depthFailOp;
+        stencilOp.passOp      = rhs.stencilOp.passOp;
+        break;
+      }
+
+      case CommandType::SET_DEPTH_COMPARE_OP:
+      {
+        depth.compareOp = rhs.depth.compareOp;
+        break;
+      }
+      case CommandType::SET_DEPTH_TEST_ENABLE:
+      {
+        depth.testEnabled = rhs.depth.testEnabled;
+        break;
+      }
+      case CommandType::SET_DEPTH_WRITE_ENABLE:
+      {
+        depth.writeEnabled = rhs.depth.writeEnabled;
+        break;
+      }
     }
     type = rhs.type;
   }
@@ -396,6 +512,42 @@ struct Command
     {
       GLES::RenderTarget* targetToPresent;
     } presentRenderTarget;
+
+    struct
+    {
+      Graphics::CompareOp compareOp;
+      bool                testEnabled;
+      bool                writeEnabled;
+    } depth;
+
+    struct
+    {
+      Graphics::StencilOp failOp;
+      Graphics::StencilOp passOp;
+      Graphics::StencilOp depthFailOp;
+    } stencilOp;
+
+    struct
+    {
+      uint32_t mask;
+    } stencilWriteMask;
+
+    struct
+    {
+      uint32_t            compareMask;
+      Graphics::CompareOp compareOp;
+      uint32_t            reference;
+    } stencilFunc;
+
+    struct
+    {
+      bool enabled;
+    } stencilTest;
+
+    struct
+    {
+      bool enabled;
+    } colorMask;
   };
 };
 
@@ -476,6 +628,30 @@ public:
 
   void SetViewportEnable(bool value) override;
 
+  void SetColorMask(bool enabled) override;
+
+  void ClearStencilBuffer() override;
+
+  void SetStencilTestEnable(bool stencilEnable) override;
+
+  void SetStencilWriteMask(uint32_t writeMask) override;
+
+  void SetStencilOp(Graphics::StencilOp failOp,
+                    Graphics::StencilOp passOp,
+                    Graphics::StencilOp depthFailOp) override;
+
+  void SetStencilFunc(Graphics::CompareOp compareOp,
+                      uint32_t            reference,
+                      uint32_t            compareMask) override;
+
+  void SetDepthCompareOp(Graphics::CompareOp compareOp) override;
+
+  void SetDepthTestEnable(bool depthTestEnable) override;
+
+  void SetDepthWriteEnable(bool depthWriteEnable) override;
+
+  void ClearDepthBuffer() override;
+
   /**
    * @brief Presents specified render target
    *
index 0e569ab..bb5d680 100644 (file)
@@ -36,9 +36,9 @@ RenderPass::RenderPass(const Graphics::RenderPassCreateInfo& createInfo, Graphic
   // copy attachment description
   if(createInfo.attachments)
   {
-    mCreateInfo.attachments = &mImpl->attachments;
     mImpl->attachments.insert(mImpl->attachments.end(), createInfo.attachments->begin(), createInfo.attachments->end());
+    mCreateInfo.attachments = &mImpl->attachments;
   }
 }
 
-} // namespace Dali::Graphics::GLES
\ No newline at end of file
+} // namespace Dali::Graphics::GLES
index 3547ffe..141fba1 100644 (file)
@@ -1335,6 +1335,76 @@ struct GLAddressMode
   GLenum texParameter{GL_CLAMP_TO_EDGE};
 };
 
+struct GLCompareOp
+{
+  constexpr explicit GLCompareOp(Graphics::CompareOp compareOp)
+  {
+    switch(compareOp)
+    {
+      case Graphics::CompareOp::NEVER:
+        op = GL_NEVER;
+        break;
+      case Graphics::CompareOp::LESS:
+        op = GL_LESS;
+        break;
+      case Graphics::CompareOp::EQUAL:
+        op = GL_EQUAL;
+        break;
+      case Graphics::CompareOp::LESS_OR_EQUAL:
+        op = GL_LEQUAL;
+        break;
+      case Graphics::CompareOp::GREATER:
+        op = GL_GREATER;
+        break;
+      case Graphics::CompareOp::NOT_EQUAL:
+        op = GL_NOTEQUAL;
+        break;
+      case Graphics::CompareOp::GREATER_OR_EQUAL:
+        op = GL_GEQUAL;
+        break;
+      case Graphics::CompareOp::ALWAYS:
+        op = GL_ALWAYS;
+        break;
+    }
+  }
+  GLenum op{GL_LESS};
+};
+
+struct GLStencilOp
+{
+  constexpr explicit GLStencilOp(Graphics::StencilOp stencilOp)
+  {
+    switch(stencilOp)
+    {
+      case Graphics::StencilOp::KEEP:
+        op = GL_KEEP;
+        break;
+      case Graphics::StencilOp::ZERO:
+        op = GL_ZERO;
+        break;
+      case Graphics::StencilOp::REPLACE:
+        op = GL_REPLACE;
+        break;
+      case Graphics::StencilOp::INCREMENT_AND_CLAMP:
+        op = GL_INCR;
+        break;
+      case Graphics::StencilOp::DECREMENT_AND_CLAMP:
+        op = GL_DECR;
+        break;
+      case Graphics::StencilOp::INVERT:
+        op = GL_INVERT;
+        break;
+      case Graphics::StencilOp::INCREMENT_AND_WRAP:
+        op = GL_INCR_WRAP;
+        break;
+      case Graphics::StencilOp::DECREMENT_AND_WRAP:
+        op = GL_DECR_WRAP;
+        break;
+    }
+  }
+  GLenum op{GL_KEEP};
+};
+
 /**
  * @brief Descriptor of single buffer binding within
  * command buffer.