Adding depth buffer to swapchain 32/318532/10
authorDavid Steele <david.steele@samsung.com>
Tue, 1 Oct 2024 09:50:51 +0000 (10:50 +0100)
committerDavid Steele <david.steele@samsung.com>
Tue, 15 Oct 2024 10:02:24 +0000 (11:02 +0100)
Changed stencil funcs in graphics-api to better match
the api calls required in both GLES and VUlkan. (Rolled
SetStencilFunc and SetStencilOp into a single SetStencilState).

Added depth buffer creation to swapchain. This should invalidate
all pipelines, as the render pass will change, but we don't have
a pipeline cache yet...

Ensured pipeline counts color attachments of render pass when
setting up blending

Changed clip space matrix to not invert Z.

Change-Id: I5a461b86a8decb7148089b722bef4d226a1c1051

31 files changed:
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
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.h
automated-tests/src/dali-vk-graphics/CMakeLists.txt
automated-tests/src/dali-vk-graphics/utc-Dali-VkClipMatrix.cpp [new file with mode: 0644]
dali/internal/graphics/gles-impl/egl-graphics-controller-debug.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.h
dali/internal/graphics/gles-impl/gles-graphics-command-buffer.cpp
dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h
dali/internal/graphics/vulkan-impl/vulkan-command-buffer-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-command-buffer-impl.h
dali/internal/graphics/vulkan-impl/vulkan-command-buffer.cpp
dali/internal/graphics/vulkan-impl/vulkan-command-buffer.h
dali/internal/graphics/vulkan-impl/vulkan-framebuffer-attachment.h [new file with mode: 0644]
dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.h
dali/internal/graphics/vulkan-impl/vulkan-framebuffer.cpp
dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.cpp
dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.h
dali/internal/graphics/vulkan-impl/vulkan-handle.h
dali/internal/graphics/vulkan-impl/vulkan-image-impl.h
dali/internal/graphics/vulkan-impl/vulkan-memory-impl.h
dali/internal/graphics/vulkan-impl/vulkan-pipeline-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.h
dali/internal/graphics/vulkan-impl/vulkan-swapchain-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-swapchain-impl.h
dali/internal/graphics/vulkan-impl/vulkan-types.h
dali/internal/graphics/vulkan/vulkan-device.cpp
dali/internal/graphics/vulkan/vulkan-device.h

index c30f1f23f5fde28131ec876c89eb2e365a03d458..9df2d0fafca901a7949ac785976274eb2fadffaf 100644 (file)
@@ -60,14 +60,13 @@ enum class CommandType
   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,
-  DRAW_NATIVE             = 1 << 27,
-  BEGIN                   = 1 << 28,
-  END                     = 1 << 29
+  SET_STENCIL_STATE       = 1 << 22,
+  SET_DEPTH_COMPARE_OP    = 1 << 23,
+  SET_DEPTH_TEST_ENABLE   = 1 << 24,
+  SET_DEPTH_WRITE_ENABLE  = 1 << 25,
+  DRAW_NATIVE             = 1 << 26,
+  BEGIN                   = 1 << 27,
+  END                     = 1 << 28
 };
 
 std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op);
@@ -346,23 +345,19 @@ struct Command
         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:
+      case CommandType::SET_STENCIL_STATE:
       {
-        data.stencilOp.failOp      = rhs.data.stencilOp.failOp;
-        data.stencilOp.depthFailOp = rhs.data.stencilOp.depthFailOp;
-        data.stencilOp.passOp      = rhs.data.stencilOp.passOp;
+        data.stencilState.compareMask = rhs.data.stencilState.compareMask;
+        data.stencilState.compareOp   = rhs.data.stencilState.compareOp;
+        data.stencilState.reference   = rhs.data.stencilState.reference;
+        data.stencilState.failOp      = rhs.data.stencilState.failOp;
+        data.stencilState.depthFailOp = rhs.data.stencilState.depthFailOp;
+        data.stencilState.passOp      = rhs.data.stencilState.passOp;
         break;
       }
 
@@ -520,18 +515,14 @@ struct Command
         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:
+      case CommandType::SET_STENCIL_STATE:
       {
-        data.stencilFunc.compareMask = rhs.data.stencilFunc.compareMask;
-        data.stencilFunc.compareOp   = rhs.data.stencilFunc.compareOp;
-        data.stencilFunc.reference   = rhs.data.stencilFunc.reference;
+        data.stencilState.failOp      = rhs.data.stencilState.failOp;
+        data.stencilState.depthFailOp = rhs.data.stencilState.depthFailOp;
+        data.stencilState.passOp      = rhs.data.stencilState.passOp;
+        data.stencilState.compareMask = rhs.data.stencilState.compareMask;
+        data.stencilState.compareOp   = rhs.data.stencilState.compareOp;
+        data.stencilState.reference   = rhs.data.stencilState.reference;
         break;
       }
       case CommandType::SET_DEPTH_COMPARE_OP:
@@ -657,20 +648,16 @@ struct Command
       Graphics::StencilOp failOp;
       Graphics::StencilOp passOp;
       Graphics::StencilOp depthFailOp;
-    } stencilOp;
+      uint32_t            compareMask;
+      Graphics::CompareOp compareOp;
+      uint32_t            reference;
+    } stencilState;
 
     struct
     {
       uint32_t mask;
     } stencilWriteMask;
 
-    struct
-    {
-      uint32_t            compareMask;
-      Graphics::CompareOp compareOp;
-      uint32_t            reference;
-    } stencilFunc;
-
     struct
     {
       bool enabled;
@@ -1033,38 +1020,29 @@ public:
     mCommands.back().data.stencilWriteMask.mask = writeMask;
   }
 
-  void SetStencilOp(Graphics::StencilOp failOp,
-                    Graphics::StencilOp passOp,
-                    Graphics::StencilOp depthFailOp) override
+  void SetStencilState(Graphics::CompareOp compareOp,
+                       uint32_t            reference,
+                       uint32_t            compareMask,
+                       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);
-
+    mCallStack.PushCall("SetStencilState", 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;
+    mCommands.back().type                          = CommandType::SET_STENCIL_STATE;
+    mCommands.back().data.stencilState.failOp      = failOp;
+    mCommands.back().data.stencilState.passOp      = passOp;
+    mCommands.back().data.stencilState.depthFailOp = depthFailOp;
+    mCommands.back().data.stencilState.compareOp   = compareOp;
+    mCommands.back().data.stencilState.compareMask = compareMask;
+    mCommands.back().data.stencilState.reference   = reference;
   }
 
   void SetDepthCompareOp(Graphics::CompareOp compareOp) override
index 114879fb4faa9ec6e36cc41e6f9dba7419e38aef..94dd8d54abbadc89a836355efbd0e8dcdc847f3c 100644 (file)
@@ -866,24 +866,19 @@ void TestGraphicsController::ProcessCommandBuffer(TestGraphicsCommandBuffer& com
         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:
+      case CommandType::SET_STENCIL_STATE:
       {
-        mGl.StencilOp(GLStencilOp(cmd.data.stencilOp.failOp).op,
-                      GLStencilOp(cmd.data.stencilOp.depthFailOp).op,
-                      GLStencilOp(cmd.data.stencilOp.passOp).op);
+        mGl.StencilFunc(GLCompareOp(cmd.data.stencilState.compareOp).op,
+                        cmd.data.stencilState.reference,
+                        cmd.data.stencilState.compareMask);
+        mGl.StencilOp(GLStencilOp(cmd.data.stencilState.failOp).op,
+                      GLStencilOp(cmd.data.stencilState.depthFailOp).op,
+                      GLStencilOp(cmd.data.stencilState.passOp).op);
         break;
       }
 
@@ -1190,13 +1185,15 @@ void TestGraphicsController::GenerateTextureMipmaps(const Graphics::Texture& tex
   mGl.GenerateMipmap(gfxTexture->GetTarget());
 }
 
-bool TestGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool enableStencil)
+bool TestGraphicsController::EnableDepthStencilBuffer(const Graphics::RenderTarget& renderTarget,
+                                                      bool                          enableDepth,
+                                                      bool                          enableStencil)
 {
   TraceCallStack::NamedParams namedParams;
   namedParams["enableDepth"] << (enableDepth ? "T" : "F");
   namedParams["enableStencil"] << (enableStencil ? "T" : "F");
-  mCallStack.PushCall("EnableDepthStencilBuffer", "", namedParams);
-  return false;
+  mCallStack.PushCall("EnableDepthStencilBuffer", namedParams.str(), namedParams);
+  return true;
 }
 
 void TestGraphicsController::RunGarbageCollector(size_t numberOfDiscardedRenderers)
index 2b0a9b97aaedb4ab9ee2facf08ba104f15b74ca6..012833dce392a22b77905b6d0725b4064597947a 100644 (file)
@@ -173,10 +173,7 @@ public:
    */
   void GenerateTextureMipmaps(const Graphics::Texture& texture) override;
 
-  /**
-   * TBD: do we need those functions in the new implementation?
-   */
-  bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override;
+  bool EnableDepthStencilBuffer(const Graphics::RenderTarget& surface, bool enableDepth, bool enableStencil) override;
 
   void RunGarbageCollector(size_t numberOfDiscardedRenderers) override;
 
index 3d36ab09190f3ef1579a0977cb541787ba69e022..c5e69cef1617d59556280f665939eec0332e22d6 100644 (file)
@@ -8,6 +8,7 @@ SET(CAPI_LIB "dali-vk-graphics")
 
 SET(TC_SOURCES
     utc-Dali-VkGraphicsBuffer.cpp
+    utc-Dali-VkClipMatrix.cpp
 )
 
 SET(TC_SOURCE_LIST ${TC_SOURCES} CACHE STRING "List of test sources")
diff --git a/automated-tests/src/dali-vk-graphics/utc-Dali-VkClipMatrix.cpp b/automated-tests/src/dali-vk-graphics/utc-Dali-VkClipMatrix.cpp
new file mode 100644 (file)
index 0000000..b853d5c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali-test-suite-utils.h>
+#include <dali/dali.h>
+
+#include <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
+#include <test-actor-utils.h>
+#include <test-graphics-framebuffer.h>
+#include <test-graphics-vk-application.h>
+
+using namespace Dali;
+
+namespace
+{
+} // namespace
+
+int UtcDaliClipMatrix01(void)
+{
+  TestGraphicsApplication app;
+  tet_infoline("UtcDaliClipMatrix01 Test that various points in clip space are mapped properly");
+
+  auto& controller = app.GetGraphicsController();
+
+  // GL clip space:
+  // Y up, x/y range: -1:1  z range -1:1
+  //
+  // Vulkan clip space:
+  // Y down, x/y range: -1:1, z range 0:1
+
+  const Vector3 testPoints[] = {Vector3(0.f, 0.f, 0.f),
+                                Vector3(-1.f, 0.f, 0.f),
+                                Vector3(1.f, 0.f, 0.f),
+                                Vector3(0.f, -1.f, 0.f),
+                                Vector3(0.f, 1.f, 0.f),
+                                Vector3(0.f, 0.f, -1.f),
+                                Vector3(0.f, 0.f, 1.f),
+                                Vector3(0.2f, 0.2f, 0.2f)};
+
+  const Vector3 resultPoints[] = {Vector3(0.f, 0.0f, 0.5f),
+                                  Vector3(-1.f, 0.f, 0.5f),
+                                  Vector3(1.f, 0.f, 0.5f),
+                                  Vector3(0.f, 1.f, 0.5f),
+                                  Vector3(0.f, -1.f, 0.5f),
+                                  Vector3(0.f, 0.f, 0.0f),
+                                  Vector3(0.f, 0.f, 1.f),
+                                  Vector3(0.2f, -0.2f, 0.6f)};
+
+  const int numTests = sizeof(testPoints) / sizeof(Vector3);
+
+  DALI_TEST_EQUALS(controller.HasClipMatrix(), true, TEST_LOCATION);
+  const Matrix& clipMatrix = controller.GetClipMatrix();
+
+  for(int i = 0; i < numTests; ++i)
+  {
+    auto testVec   = Vector4(testPoints[i].x, testPoints[i].y, testPoints[i].z, 1.0f);
+    auto resultVec = Vector4(resultPoints[i].x, resultPoints[i].y, resultPoints[i].z, 1.0f);
+
+    auto outVec = clipMatrix * testVec;
+    tet_printf(
+      "In Vec: (%3.1f, %3.1f, %3.1f) => Out vec: (%3.1f, %3.1f, %3.1f)\n"
+      "                            Expected: (%3.1f, %3.1f, %3.1f)    %s\n",
+      testPoints[i].x,
+      testPoints[i].y,
+      testPoints[i].z,
+      outVec.x,
+      outVec.y,
+      outVec.z,
+      resultVec.x,
+      resultVec.y,
+      resultVec.z,
+      resultVec == outVec ? "PASS" : "FAIL");
+    DALI_TEST_EQUALS(outVec, resultVec, TEST_LOCATION);
+  }
+
+  END_TEST;
+}
index bec34c726727449b01ae466dd76259400137da30..e02e188160838f30caf747ab5fb0c7afde820309 100644 (file)
@@ -196,16 +196,22 @@ void DumpCommandBuffer(FILE* output, const GLES::CommandBuffer* commandBuffer)
         break;
       }
 
-      case GLES::CommandType::SET_STENCIL_FUNC:
+      case GLES::CommandType::SET_STENCIL_STATE:
       {
         fprintf(output,
-                "{\"Cmd\":\"STENCIL_FUNC\",\n"
+                "{\"Cmd\":\"STENCIL_STATE\",\n"
                 "\"compareOp\":\"%s\",\n"
                 "\"reference\":\"0x%x\",\n"
-                "\"compareMask\":\"0x%x\"\n}",
-                DumpCompareOp(cmd.stencilFunc.compareOp).c_str(),
-                cmd.stencilFunc.reference,
-                cmd.stencilFunc.compareMask);
+                "\"compareMask\":\"0x%x\"\n"
+                "\"failOp\":\"%s\",\n"
+                "\"depthFailOp\":\"%s\",\n"
+                "\"passOp\":\"%s\"\n}",
+                DumpCompareOp(cmd.stencilState.compareOp).c_str(),
+                cmd.stencilState.reference,
+                cmd.stencilState.compareMask,
+                DumpStencilOp(cmd.stencilState.failOp).c_str(),
+                DumpStencilOp(cmd.stencilState.depthFailOp).c_str(),
+                DumpStencilOp(cmd.stencilState.passOp).c_str());
         break;
       }
 
@@ -215,20 +221,6 @@ void DumpCommandBuffer(FILE* output, const GLES::CommandBuffer* commandBuffer)
         break;
       }
 
-      case GLES::CommandType::SET_STENCIL_OP:
-      {
-        fprintf(output,
-                "{\"Cmd\":\"SET_STENCIL_OP\",\n"
-                "\"failOp\":\"%s\",\n"
-                "\"depthFailOp\":\"%s\",\n"
-                "\"passOp\":\"%s\"\n}",
-
-                DumpStencilOp(cmd.stencilOp.failOp).c_str(),
-                DumpStencilOp(cmd.stencilOp.depthFailOp).c_str(),
-                DumpStencilOp(cmd.stencilOp.passOp).c_str());
-        break;
-      }
-
       case GLES::CommandType::SET_DEPTH_COMPARE_OP:
       {
         fprintf(output,
index 8a63e50f7762ec6eb30fb6585e0571298684b208..307e00b0adfda9f9ccd54d0429d7bab4d6fc2798 100644 (file)
@@ -638,11 +638,14 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm
         break;
       }
 
-      case GLES::CommandType::SET_STENCIL_FUNC:
+      case GLES::CommandType::SET_STENCIL_STATE:
       {
-        mCurrentContext->StencilFunc(cmd.stencilFunc.compareOp,
-                                     cmd.stencilFunc.reference,
-                                     cmd.stencilFunc.compareMask);
+        mCurrentContext->StencilFunc(cmd.stencilState.compareOp,
+                                     cmd.stencilState.reference,
+                                     cmd.stencilState.compareMask);
+        mCurrentContext->StencilOp(cmd.stencilState.failOp,
+                                   cmd.stencilState.depthFailOp,
+                                   cmd.stencilState.passOp);
         break;
       }
 
@@ -652,14 +655,6 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm
         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);
index b14a5aa229843ed73a419f1d2e15edd824372ced..48150a6a730c828f36971b01c8e42f94c376466e 100644 (file)
@@ -170,7 +170,7 @@ public:
   /**
    * @copydoc Dali::Graphics::EnableDepthStencilBuffer()
    */
-  bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override
+  bool EnableDepthStencilBuffer(const Graphics::RenderTarget& renderTarget, bool enableDepth, bool enableStencil) override
   {
     return {};
   }
index 776711fc7156ab32b52ce3d8a36dcc882fe1a8e2..888c1892d2ebd121f6f27a681945706f29d772d6 100644 (file)
@@ -524,23 +524,18 @@ void CommandBuffer::SetStencilWriteMask(uint32_t writeMask)
   command->stencilWriteMask.mask = writeMask;
 }
 
-void CommandBuffer::SetStencilOp(Graphics::StencilOp failOp,
-                                 Graphics::StencilOp passOp,
-                                 Graphics::StencilOp depthFailOp)
-{
-  auto  command   = mCommandPool->AllocateCommand(CommandType::SET_STENCIL_OP);
-  auto& cmd       = command->stencilOp;
+void CommandBuffer::SetStencilState(Graphics::CompareOp compareOp,
+                                    uint32_t            reference,
+                                    uint32_t            compareMask,
+                                    Graphics::StencilOp failOp,
+                                    Graphics::StencilOp passOp,
+                                    Graphics::StencilOp depthFailOp)
+{
+  auto  command   = mCommandPool->AllocateCommand(CommandType::SET_STENCIL_STATE);
+  auto& cmd       = command->stencilState;
   cmd.failOp      = failOp;
   cmd.passOp      = passOp;
   cmd.depthFailOp = depthFailOp;
-}
-
-void CommandBuffer::SetStencilFunc(Graphics::CompareOp compareOp,
-                                   uint32_t            reference,
-                                   uint32_t            compareMask)
-{
-  auto  command   = mCommandPool->AllocateCommand(CommandType::SET_STENCIL_FUNC);
-  auto& cmd       = command->stencilFunc;
   cmd.compareOp   = compareOp;
   cmd.compareMask = compareMask;
   cmd.reference   = reference;
index cbba28b1eadabd6ec8b962d3053b86f5c2d1cdcb..ebe198d3041d22619782fc4d312b608a08953e26 100644 (file)
@@ -61,8 +61,7 @@ enum class CommandType
   CLEAR_DEPTH_BUFFER,
   SET_STENCIL_TEST_ENABLE,
   SET_STENCIL_WRITE_MASK,
-  SET_STENCIL_OP,
-  SET_STENCIL_FUNC,
+  SET_STENCIL_STATE,
   SET_DEPTH_COMPARE_OP,
   SET_DEPTH_TEST_ENABLE,
   SET_DEPTH_WRITE_ENABLE,
@@ -188,13 +187,6 @@ struct Command
       bool                writeEnabled;
     } depth;
 
-    struct
-    {
-      Graphics::StencilOp failOp;
-      Graphics::StencilOp passOp;
-      Graphics::StencilOp depthFailOp;
-    } stencilOp;
-
     struct
     {
       uint32_t mask;
@@ -202,10 +194,14 @@ struct Command
 
     struct
     {
-      uint32_t            compareMask;
       Graphics::CompareOp compareOp;
+      uint32_t            compareMask;
       uint32_t            reference;
-    } stencilFunc;
+
+      Graphics::StencilOp failOp;
+      Graphics::StencilOp passOp;
+      Graphics::StencilOp depthFailOp;
+    } stencilState;
 
     struct
     {
@@ -382,18 +378,14 @@ public:
   void SetStencilWriteMask(uint32_t writeMask) override;
 
   /**
-   * @copydoc Dali::Graphics::CommandBuffer::SetStencilOp
-   */
-  void SetStencilOp(Graphics::StencilOp failOp,
-                    Graphics::StencilOp passOp,
-                    Graphics::StencilOp depthFailOp) override;
-
-  /**
-   * @copydoc Dali::Graphics::CommandBuffer::SetStencilFunc
+   * @copydoc Dali::Graphics::CommandBuffer::SetStencilState
    */
-  void SetStencilFunc(Graphics::CompareOp compareOp,
-                      uint32_t            reference,
-                      uint32_t            compareMask) override;
+  void SetStencilState(Graphics::CompareOp compareOp,
+                       uint32_t            reference,
+                       uint32_t            compareMask,
+                       Graphics::StencilOp failOp,
+                       Graphics::StencilOp passOp,
+                       Graphics::StencilOp depthFailOp) override;
 
   /**
    * @copydoc Dali::Graphics::CommandBuffer::SetDepthCompareOp
index 200f3f829ba04578d1dd9ea5e377f18b99db7ade..e429a6a79e2b86e628fae77df0b00b9d672adcf6 100644 (file)
@@ -367,6 +367,55 @@ void CommandBufferImpl::SetViewport(Viewport value)
   mCommandBuffer.setViewport(0, 1, reinterpret_cast<vk::Viewport*>(&value));
 }
 
+void CommandBufferImpl::SetStencilTestEnable(bool stencilEnable)
+{
+  mCommandBuffer.setStencilTestEnable(stencilEnable);
+  if(!stencilEnable)
+  {
+    mCommandBuffer.setStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack, 0x00);
+    mCommandBuffer.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack, 0x00);
+    mCommandBuffer.setStencilReference(vk::StencilFaceFlagBits::eFrontAndBack, 0x00);
+    mCommandBuffer.setStencilOp(vk::StencilFaceFlagBits::eFrontAndBack, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eLess);
+  }
+}
+
+void CommandBufferImpl::SetStencilWriteMask(vk::StencilFaceFlags faceMask, uint32_t writeMask)
+{
+  mCommandBuffer.setStencilWriteMask(faceMask, writeMask);
+}
+
+void CommandBufferImpl::SetStencilCompareMask(vk::StencilFaceFlags faceMask, uint32_t compareMask)
+{
+  mCommandBuffer.setStencilCompareMask(faceMask, compareMask);
+}
+
+void CommandBufferImpl::SetStencilReference(vk::StencilFaceFlags faceMask, uint32_t reference)
+{
+  mCommandBuffer.setStencilReference(faceMask, reference);
+}
+
+void CommandBufferImpl::SetStencilOp(vk::StencilFaceFlags faceMask, vk::StencilOp failOp, vk::StencilOp passOp, vk::StencilOp depthFailOp, vk::CompareOp compareOp)
+{
+  mCommandBuffer.setStencilOp(faceMask, failOp, passOp, depthFailOp, compareOp);
+}
+
+void CommandBufferImpl::SetDepthTestEnable(bool depthTestEnable)
+{
+  mCommandBuffer.setDepthTestEnable(depthTestEnable);
+  mCommandBuffer.setDepthBoundsTestEnable(false);
+  mCommandBuffer.setDepthBounds(0.0f, 1.0f);
+}
+
+void CommandBufferImpl::SetDepthWriteEnable(bool depthWriteEnable)
+{
+  mCommandBuffer.setDepthWriteEnable(depthWriteEnable);
+}
+
+void CommandBufferImpl::SetDepthCompareOp(vk::CompareOp op)
+{
+  mCommandBuffer.setDepthCompareOp(op);
+}
+
 void CommandBufferImpl::BindResources(vk::DescriptorSet descriptorSet)
 {
   std::vector<vk::DescriptorImageInfo>  imageInfos;
index 73c0323abf14664250948c2a5a7aabe3a91e0622..98b4db802055a02aac8d7f00bef55fae48915fe9 100644 (file)
@@ -106,6 +106,16 @@ public:
   void SetScissor(Rect2D value);
   void SetViewport(Viewport value);
 
+  void SetStencilTestEnable(bool stencilEnable);
+  void SetStencilWriteMask(vk::StencilFaceFlags faceMask, uint32_t writeMask);
+  void SetStencilCompareMask(vk::StencilFaceFlags faceMask, uint32_t compareMask);
+  void SetStencilReference(vk::StencilFaceFlags faceMask, uint32_t reference);
+  void SetStencilOp(vk::StencilFaceFlags faceMask, vk::StencilOp failOp, vk::StencilOp passOp, vk::StencilOp depthFailOp, vk::CompareOp compareOp);
+
+  void SetDepthTestEnable(bool depthTestEnable);
+  void SetDepthWriteEnable(bool depthWriteEnable);
+  void SetDepthCompareOp(vk::CompareOp compareOp);
+
   void Draw(
     uint32_t vertexCount,
     uint32_t instanceCount,
index 922bb391ad372ab9ab606d09d19e3d871e7dcb13..9e743ee26242556ce5d74ac130bc2dcb2b0b1584 100644 (file)
@@ -306,42 +306,88 @@ void CommandBuffer::SetColorMask(bool enabled)
 
 void CommandBuffer::ClearStencilBuffer()
 {
+  // Ignore, we should only do this in render pass
 }
 
 void CommandBuffer::ClearDepthBuffer()
 {
+  // Ignore, we should only do this in render pass
 }
 
 void CommandBuffer::SetStencilTestEnable(bool stencilEnable)
 {
+  mCommandBufferImpl->SetStencilTestEnable(stencilEnable);
 }
 
 void CommandBuffer::SetStencilWriteMask(uint32_t writeMask)
 {
+  mCommandBufferImpl->SetStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack, writeMask);
 }
 
-void CommandBuffer::SetStencilFunc(Graphics::CompareOp compareOp,
-                                   uint32_t            reference,
-                                   uint32_t            compareMask)
-{
-}
-
-void CommandBuffer::SetStencilOp(Graphics::StencilOp failOp,
-                                 Graphics::StencilOp passOp,
-                                 Graphics::StencilOp depthFailOp)
+void CommandBuffer::SetStencilState(Graphics::CompareOp compareOp,
+                                    uint32_t            reference,
+                                    uint32_t            compareMask,
+                                    Graphics::StencilOp failOp,
+                                    Graphics::StencilOp passOp,
+                                    Graphics::StencilOp depthFailOp)
 {
+  mCommandBufferImpl->SetStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack, compareMask);
+  mCommandBufferImpl->SetStencilReference(vk::StencilFaceFlagBits::eFrontAndBack, reference);
+  mCommandBufferImpl->SetStencilOp(vk::StencilFaceFlagBits::eFrontAndBack,
+                                   VkStencilOpType(failOp).op,
+                                   VkStencilOpType(passOp).op,
+                                   VkStencilOpType(depthFailOp).op,
+                                   VkCompareOpType(compareOp).op);
 }
 
 void CommandBuffer::SetDepthCompareOp(Graphics::CompareOp compareOp)
 {
+  // @todo Invert comparison
+  // This makes depth test work, but implies that the conversion to NDC has the wrong sense.
+  vk::CompareOp depthOp;
+  switch(compareOp)
+  {
+    case Graphics::CompareOp::NEVER:
+    case Graphics::CompareOp::EQUAL:
+    case Graphics::CompareOp::NOT_EQUAL:
+    case Graphics::CompareOp::ALWAYS:
+    {
+      depthOp = VkCompareOpType(compareOp).op;
+      break;
+    }
+    case Graphics::CompareOp::LESS:
+    {
+      depthOp = vk::CompareOp::eGreaterOrEqual;
+      break;
+    }
+    case Graphics::CompareOp::LESS_OR_EQUAL:
+    {
+      depthOp = vk::CompareOp::eGreater;
+      break;
+    }
+    case Graphics::CompareOp::GREATER:
+    {
+      depthOp = vk::CompareOp::eLessOrEqual;
+      break;
+    }
+    case Graphics::CompareOp::GREATER_OR_EQUAL:
+    {
+      depthOp = vk::CompareOp::eLess;
+      break;
+    }
+  }
+  depthOp = VkCompareOpType(compareOp).op;
+  mCommandBufferImpl->SetDepthCompareOp(depthOp);
 }
 
 void CommandBuffer::SetDepthTestEnable(bool depthTestEnable)
 {
+  mCommandBufferImpl->SetDepthTestEnable(depthTestEnable);
 }
 
 void CommandBuffer::SetDepthWriteEnable(bool depthWriteEnable)
 {
+  mCommandBufferImpl->SetDepthWriteEnable(depthWriteEnable);
 }
 
 Swapchain* CommandBuffer::GetLastSwapchain() const
index fe6f42510035fb745abccf68d11116e8a6840cf8..acdbaf231ee0f2560ca7b8f091d5b34c74f7b0f2 100644 (file)
@@ -281,25 +281,21 @@ public:
   void SetStencilWriteMask(uint32_t writeMask) override;
 
   /**
-   * @brief Setup the stencil function
+   * @brief Setup the stencil function and how subsequent draws will affect the stencil buffer.
    *
-   * @param[in] compareOp How the stencil buffer, reference and compareMask are combined to determine whether to draw a pixel or not.
-   * @param[in] reference A reference value that is ANDed with the mask in the compare op.
-   * @param[in] compareMask The bitplanes from the stencil buffer that are active.
-   */
-  void SetStencilFunc(Graphics::CompareOp compareOp,
-                      uint32_t            reference,
-                      uint32_t            compareMask) override;
-
-  /**
-   * @brief Set how subsequent draws will affect the stencil buffer.
    * @param[in] failOp What happens to stencil buffer if drawing a pixel fails the stencil test
    * @param[in] passOp What happens to stencil buffer if drawing a pixel passes stencil & depth test
    * @param[in] depthFailOp What happens to stencil buffer if drawing a pixel passes stencil but fails depth test.
+   * @param[in] compareOp How the stencil buffer, reference and compareMask are combined to determine whether to draw a pixel or not.
+   * @param[in] reference A reference value that is ANDed with the mask in the compare op.
+   * @param[in] compareMask The bitplanes from the stencil buffer that are active.
    */
-  void SetStencilOp(Graphics::StencilOp failOp,
-                    Graphics::StencilOp passOp,
-                    Graphics::StencilOp depthFailOp) override;
+  void SetStencilState(Graphics::CompareOp compareOp,
+                       uint32_t            reference,
+                       uint32_t            compareMask,
+                       Graphics::StencilOp failOp,
+                       Graphics::StencilOp passOp,
+                       Graphics::StencilOp depthFailOp) override;
 
   /**
    * @brief Defines the comparison operator for passing the depth test.
diff --git a/dali/internal/graphics/vulkan-impl/vulkan-framebuffer-attachment.h b/dali/internal/graphics/vulkan-impl/vulkan-framebuffer-attachment.h
new file mode 100644 (file)
index 0000000..ab03167
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef DALI_GRAPHICS_VULKAN_FRAMEBUFFER_ATTACHMENT_H
+#define DALI_GRAPHICS_VULKAN_FRAMEBUFFER_ATTACHMENT_H
+
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/internal/graphics/vulkan-impl/vulkan-handle.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
+
+namespace Dali::Graphics::Vulkan
+{
+class ImageView;
+
+enum class AttachmentType
+{
+  COLOR,
+  DEPTH_STENCIL,
+  INPUT,
+  RESOLVE,
+  PRESERVE,
+  UNDEFINED
+};
+
+class FramebufferAttachment : public VkSharedResource
+{
+public:
+  /**
+   * Constructor
+   *
+   * @param[in] imageView The imageview of the attachment
+   * @param[in] clearColor The color used to clear this attachment during CLEAR_OP
+   * @param[in] type The attachment type (usually COLOR or DEPTH_STENCIL)
+   * @param[in] presentable Whether the attachment is presentable (changes final layout)
+   */
+  FramebufferAttachment(std::unique_ptr<ImageView>& imageView,
+                        vk::ClearValue              clearColor,
+                        AttachmentType              type,
+                        bool                        presentable);
+
+  /**
+   * Creates a new color attachment.
+   *
+   * @param[in] imageView The imageview of the attachment
+   * @param[in] clearColorValue The color used to clear this attachment during CLEAR_OP
+   * @param[in] presentable Whether the attachment is presentable (changes final layout)
+   */
+  static FramebufferAttachment* NewColorAttachment(std::unique_ptr<ImageView>& imageView,
+                                                   vk::ClearColorValue         clearColorValue,
+                                                   bool                        presentable);
+
+  /**
+   * Creates a new depth attachment.
+   *
+   * @param[in] imageView The imageview of the attachment
+   * @param[in] clearDepthStencilValue The value used to clear this attachment during CLEAR_OP
+   */
+  static FramebufferAttachment* NewDepthAttachment(std::unique_ptr<ImageView>& imageView,
+                                                   vk::ClearDepthStencilValue  clearDepthStencilValue);
+
+  [[nodiscard]] ImageView* GetImageView() const;
+
+  [[nodiscard]] const vk::AttachmentDescription& GetDescription() const;
+
+  [[nodiscard]] const vk::ClearValue& GetClearValue() const;
+
+  [[nodiscard]] AttachmentType GetType() const;
+
+  [[nodiscard]] bool IsValid() const;
+
+private:
+  FramebufferAttachment() = default;
+
+  std::unique_ptr<ImageView> mImageView;
+  vk::AttachmentDescription  mDescription;
+  vk::ClearValue             mClearValue;
+  AttachmentType             mType{AttachmentType::UNDEFINED};
+};
+
+using FramebufferAttachmentHandle = Vulkan::Handle<FramebufferAttachment>; // Can share attachments
+using SharedAttachments           = std::vector<FramebufferAttachmentHandle>;
+
+} // namespace Dali::Graphics::Vulkan
+
+#endif // DALI_GRAPHICS_VULKAN_FRAMEBUFFER_ATTACHMENT_H
index 4e5d556f5ee9fc68c65220c3b5ac31da47afb052..b1bed3935b78e595d49d1f72e148ba2a7cb00dbf 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.h>
 
+#include <dali/internal/graphics/vulkan-impl/vulkan-handle.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-image-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-image-view-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.h>
@@ -118,12 +119,12 @@ bool FramebufferAttachment::IsValid() const
 // FramebufferImpl -------------------------------
 
 FramebufferImpl* FramebufferImpl::New(
-  Vulkan::Device&   device,
-  RenderPassHandle  renderPass,
-  OwnedAttachments& attachments,
-  uint32_t          width,
-  uint32_t          height,
-  bool              hasDepthAttachments)
+  Vulkan::Device&    device,
+  RenderPassHandle   renderPass,
+  SharedAttachments& attachments,
+  uint32_t           width,
+  uint32_t           height,
+  bool               hasDepthAttachments)
 {
   DALI_ASSERT_ALWAYS(renderPass && "You require more render passes!");
 
@@ -153,20 +154,20 @@ FramebufferImpl* FramebufferImpl::New(
 }
 
 FramebufferImpl* FramebufferImpl::New(
-  Vulkan::Device&                         device,
-  RenderPassHandle                        renderPass,
-  OwnedAttachments&                       colorAttachments,
-  std::unique_ptr<FramebufferAttachment>& depthAttachment,
-  uint32_t                                width,
-  uint32_t                                height)
+  Vulkan::Device&             device,
+  RenderPassHandle            renderPass,
+  SharedAttachments&          colorAttachments,
+  FramebufferAttachmentHandle depthAttachment,
+  uint32_t                    width,
+  uint32_t                    height)
 {
   assert((!colorAttachments.empty() || depthAttachment) && "Cannot create framebuffer. Please provide at least one attachment");
 
-  auto                                colorAttachmentsValid = true;
-  std::vector<FramebufferAttachment*> attachments;
+  auto              colorAttachmentsValid = true;
+  SharedAttachments attachments;
   for(auto& attachment : colorAttachments)
   {
-    attachments.emplace_back(attachment.get());
+    attachments.emplace_back(attachment);
     if(!attachment->IsValid())
     {
       colorAttachmentsValid = false;
@@ -190,28 +191,27 @@ FramebufferImpl* FramebufferImpl::New(
   if(!renderPass)
   {
     // Create compatible vulkan render pass
-    renderPass = RenderPassImpl::New(device, attachments, depthAttachment.get());
+    renderPass = RenderPassImpl::New(device, attachments, depthAttachment);
   }
 
-  OwnedAttachments ownedAttachments(std::move(colorAttachments));
   if(hasDepth)
   {
-    ownedAttachments.emplace_back(std::move(depthAttachment));
+    attachments.emplace_back(std::move(depthAttachment));
   }
-  return FramebufferImpl::New(device, renderPass, ownedAttachments, width, height, hasDepth);
+  return FramebufferImpl::New(device, renderPass, attachments, width, height, hasDepth);
 }
 
-FramebufferImpl::FramebufferImpl(Device&           graphicsDevice,
-                                 OwnedAttachments& attachments,
-                                 vk::Framebuffer   vkHandle,
-                                 RenderPassHandle  renderPassImpl,
-                                 uint32_t          width,
-                                 uint32_t          height,
-                                 bool              hasDepthAttachment)
+FramebufferImpl::FramebufferImpl(Device&            graphicsDevice,
+                                 SharedAttachments& attachments,
+                                 vk::Framebuffer    vkHandle,
+                                 RenderPassHandle   renderPassImpl,
+                                 uint32_t           width,
+                                 uint32_t           height,
+                                 bool               hasDepthAttachment)
 : mGraphicsDevice(&graphicsDevice),
   mWidth(width),
   mHeight(height),
-  mAttachments(std::move(attachments)),
+  mAttachments(attachments),
   mFramebuffer(vkHandle),
   mHasDepthAttachment(hasDepthAttachment)
 {
@@ -245,19 +245,19 @@ uint32_t FramebufferImpl::GetHeight() const
   return mHeight;
 }
 
-FramebufferAttachment* FramebufferImpl::GetAttachment(AttachmentType type, uint32_t index) const
+FramebufferAttachmentHandle FramebufferImpl::GetAttachment(AttachmentType type, uint32_t index) const
 {
   switch(type)
   {
     case AttachmentType::COLOR:
     {
-      return mAttachments[index].get();
+      return mAttachments[index];
     }
     case AttachmentType::DEPTH_STENCIL:
     {
       if(mHasDepthAttachment)
       {
-        return mAttachments.back().get();
+        return mAttachments.back();
       }
     }
     case AttachmentType::INPUT:
@@ -267,12 +267,12 @@ FramebufferAttachment* FramebufferImpl::GetAttachment(AttachmentType type, uint3
       break;
   }
 
-  return nullptr;
+  return {};
 }
 
-std::vector<FramebufferAttachment*> FramebufferImpl::GetAttachments(AttachmentType type) const
+SharedAttachments FramebufferImpl::GetAttachments(AttachmentType type) const
 {
-  auto retval = std::vector<FramebufferAttachment*>{};
+  auto retval = SharedAttachments{};
   switch(type)
   {
     case AttachmentType::COLOR:
@@ -281,7 +281,7 @@ std::vector<FramebufferAttachment*> FramebufferImpl::GetAttachments(AttachmentTy
       retval.reserve(numColorAttachments);
       for(size_t i = 0; i < numColorAttachments; ++i)
       {
-        retval.emplace_back(mAttachments[i].get());
+        retval.emplace_back(&*mAttachments[i]);
       }
       break;
     }
@@ -290,7 +290,7 @@ std::vector<FramebufferAttachment*> FramebufferImpl::GetAttachments(AttachmentTy
       if(mHasDepthAttachment)
       {
         retval.reserve(1);
-        retval.emplace_back(mAttachments.back().get());
+        retval.emplace_back(&*mAttachments.back());
       }
       break;
     }
index 16e4ea66b9e2cae50cfaba3a3014d6a19b63140e..da1b49209fcd76748ea439a3181df8812c382603 100644 (file)
 
 #include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
 
+#include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-attachment.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-image-view-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.h>
 
 namespace Dali::Graphics::Vulkan
 {
 class RenderPass;
-
-enum class AttachmentType
-{
-  COLOR,
-  DEPTH_STENCIL,
-  INPUT,
-  RESOLVE,
-  PRESERVE,
-  UNDEFINED
-};
-
 class Device;
 
-class FramebufferAttachment
-{
-public:
-  /**
-   * Constructor
-   *
-   * @param[in] imageView The imageview of the attachment
-   * @param[in] clearColor The color used to clear this attachment during CLEAR_OP
-   * @param[in] type The attachment type (usually COLOR or DEPTH_STENCIL)
-   * @param[in] presentable Whether the attachment is presentable (changes final layout)
-   */
-  FramebufferAttachment(std::unique_ptr<ImageView>& imageView,
-                        vk::ClearValue              clearColor,
-                        AttachmentType              type,
-                        bool                        presentable);
-
-  /**
-   * Creates a new color attachment.
-   *
-   * @param[in] imageView The imageview of the attachment
-   * @param[in] clearColorValue The color used to clear this attachment during CLEAR_OP
-   * @param[in] presentable Whether the attachment is presentable (changes final layout)
-   */
-  static FramebufferAttachment* NewColorAttachment(std::unique_ptr<ImageView>& imageView,
-                                                   vk::ClearColorValue         clearColorValue,
-                                                   bool                        presentable);
-
-  /**
-   * Creates a new depth attachment.
-   *
-   * @param[in] imageView The imageview of the attachment
-   * @param[in] clearDepthStencilValue The value used to clear this attachment during CLEAR_OP
-   */
-  static FramebufferAttachment* NewDepthAttachment(std::unique_ptr<ImageView>& imageView,
-                                                   vk::ClearDepthStencilValue  clearDepthStencilValue);
-
-  [[nodiscard]] ImageView* GetImageView() const;
-
-  [[nodiscard]] const vk::AttachmentDescription& GetDescription() const;
-
-  [[nodiscard]] const vk::ClearValue& GetClearValue() const;
-
-  [[nodiscard]] AttachmentType GetType() const;
-
-  [[nodiscard]] bool IsValid() const;
-
-private:
-  FramebufferAttachment() = default;
-
-  std::unique_ptr<ImageView> mImageView;
-  vk::AttachmentDescription  mDescription;
-  vk::ClearValue             mClearValue;
-  AttachmentType             mType{AttachmentType::UNDEFINED};
-};
-
-using OwnedAttachments = std::vector<std::unique_ptr<FramebufferAttachment>>;
-
 /**
  * FramebufferImpl encapsulates following objects:
  * - Images ( attachments )
@@ -119,12 +52,12 @@ public:
    * @return A new framebuffer object
    */
   static FramebufferImpl* New(
-    Vulkan::Device&   device,
-    RenderPassHandle  renderPass,
-    OwnedAttachments& attachments,
-    uint32_t          width,
-    uint32_t          height,
-    bool              hasDepthAttachment);
+    Vulkan::Device&    device,
+    RenderPassHandle   renderPass,
+    SharedAttachments& attachments,
+    uint32_t           width,
+    uint32_t           height,
+    bool               hasDepthAttachment);
 
   /**
    * @brief Create a new Framebuffer
@@ -139,12 +72,12 @@ public:
    * @return A new framebuffer object
    */
   static FramebufferImpl* New(
-    Vulkan::Device&                         device,
-    RenderPassHandle                        renderPass,
-    OwnedAttachments&                       colorAttachments,
-    std::unique_ptr<FramebufferAttachment>& depthAttachment,
-    uint32_t                                width,
-    uint32_t                                height);
+    Vulkan::Device&             device,
+    RenderPassHandle            renderPass,
+    SharedAttachments&          colorAttachments,
+    FramebufferAttachmentHandle depthAttachment,
+    uint32_t                    width,
+    uint32_t                    height);
 
   /**
    * @brief Constructor
@@ -157,13 +90,13 @@ public:
    * @param[in] height Height of the framebuffer
    * @param[in] hasDepthAttachment True if the last attachment is a depth buffer
    */
-  FramebufferImpl(Device&           graphicsDevice,
-                  OwnedAttachments& attachments,
-                  vk::Framebuffer   vkHandle,
-                  RenderPassHandle  renderPass,
-                  uint32_t          width,
-                  uint32_t          height,
-                  bool              hasDepthAttachment);
+  FramebufferImpl(Device&            graphicsDevice,
+                  SharedAttachments& attachments,
+                  vk::Framebuffer    vkHandle,
+                  RenderPassHandle   renderPass,
+                  uint32_t           width,
+                  uint32_t           height,
+                  bool               hasDepthAttachment);
 
   void Destroy();
 
@@ -171,9 +104,9 @@ public:
 
   [[nodiscard]] uint32_t GetHeight() const;
 
-  [[nodiscard]] FramebufferAttachment* GetAttachment(AttachmentType type, uint32_t index) const;
+  [[nodiscard]] FramebufferAttachmentHandle GetAttachment(AttachmentType type, uint32_t index) const;
 
-  [[nodiscard]] std::vector<FramebufferAttachment*> GetAttachments(AttachmentType type) const;
+  [[nodiscard]] SharedAttachments GetAttachments(AttachmentType type) const;
 
   [[nodiscard]] uint32_t GetAttachmentCount(AttachmentType type) const;
 
@@ -203,10 +136,10 @@ private:
   };
   using RenderPasses = std::vector<RenderPassMapElement>;
 
-  OwnedAttachments mAttachments;
-  vk::Framebuffer  mFramebuffer;
-  RenderPasses     mRenderPasses;
-  bool             mHasDepthAttachment{false};
+  SharedAttachments mAttachments;
+  vk::Framebuffer   mFramebuffer;
+  RenderPasses      mRenderPasses;
+  bool              mHasDepthAttachment{false};
 };
 
 } // Namespace Dali::Graphics::Vulkan
index 7209950b877c0be61ca848e1d19746fac9ac5d5d..c95a952efb2efdda06d341495ba31bf810a62bc0 100644 (file)
@@ -35,13 +35,13 @@ Framebuffer::~Framebuffer() = default;
 bool Framebuffer::InitializeResource()
 {
   // Create attachments
-  OwnedAttachments colorAttachments;
+  SharedAttachments colorAttachments;
   // for(auto& attachment : mCreateInfo.colorAttachments)
   {
     // auto graphicsTexture = static_cast<const Vulkan::Texture*>(attachment.texture);
     // colorAttachments.push_back(FramebufferAttachment::NewColorAttachment(attachment.texture->GetVkHandle(), clearColor, AttachmentType::COLOR, false);
   }
-  std::unique_ptr<FramebufferAttachment> depthStencilAttachment;
+  FramebufferAttachmentHandle depthStencilAttachment;
   if(mCreateInfo.depthStencilAttachment.depthTexture || mCreateInfo.depthStencilAttachment.stencilTexture)
   {
     // depthStencilAttachment = FramebufferAttachment::NewDepthAttachment();
index e125df43d3501b8f38643313c2003d5d84b13e3a..a7e7c2fa5119c98290c6d0bb47ef8bd848c76617 100644 (file)
@@ -139,6 +139,15 @@ T0* CastObject(T1* apiObject)
   return static_cast<T0*>(apiObject);
 }
 
+namespace DepthStencilFlagBits
+{
+static constexpr uint32_t DEPTH_BUFFER_BIT   = 1; // depth buffer enabled
+static constexpr uint32_t STENCIL_BUFFER_BIT = 2; // stencil buffer enabled
+} // namespace DepthStencilFlagBits
+
+// State of the depth-stencil buffer
+using DepthStencilFlags = uint32_t;
+
 struct VulkanGraphicsController::Impl
 {
   explicit Impl(VulkanGraphicsController& controller)
@@ -182,8 +191,50 @@ struct VulkanGraphicsController::Impl
     }
   }
 
+  bool EnableDepthStencilBuffer(const RenderTarget& renderTarget, bool enableDepth, bool enableStencil)
+  {
+    auto surface = static_cast<const Vulkan::RenderTarget*>(&renderTarget)->GetSurface();
+    if(!surface)
+    {
+      // Do nothing if this is not a surface.
+      return false;
+    }
+
+    auto renderSurface = static_cast<Internal::Adaptor::WindowRenderSurface*>(surface);
+    auto surfaceId     = renderSurface->GetSurfaceId();
+
+    mDepthStencilBufferRequestedState = (enableDepth ? DepthStencilFlagBits::DEPTH_BUFFER_BIT : 0u) |
+                                        (enableStencil ? DepthStencilFlagBits::STENCIL_BUFFER_BIT : 0u);
+
+    auto retval = mDepthStencilBufferRequestedState != mDepthStencilBufferCurrentState;
+
+    // @todo move state vars to surface
+    if(surface && mDepthStencilBufferCurrentState != mDepthStencilBufferRequestedState)
+    {
+      DALI_LOG_INFO(gVulkanFilter, Debug::Verbose, "UpdateDepthStencilBuffer(): New state: DEPTH: %d, STENCIL: %d\n", int(mDepthStencilBufferRequestedState & 1), int((mDepthStencilBufferRequestedState >> 1) & 1));
+
+      // Formats
+      const std::array<vk::Format, 4> DEPTH_STENCIL_FORMATS = {
+        vk::Format::eUndefined,     // no depth nor stencil needed
+        vk::Format::eD16Unorm,      // only depth buffer
+        vk::Format::eS8Uint,        // only stencil buffer
+        vk::Format::eD24UnormS8Uint // depth and stencil buffers
+      };
+
+      mGraphicsDevice->DeviceWaitIdle();
+
+      mGraphicsDevice->GetSwapchainForSurfaceId(surfaceId)->SetDepthStencil(DEPTH_STENCIL_FORMATS[mDepthStencilBufferRequestedState]);
+
+      // make sure GPU finished any pending work
+      mGraphicsDevice->DeviceWaitIdle();
+
+      mDepthStencilBufferCurrentState = mDepthStencilBufferRequestedState;
+    }
+    return retval;
+  }
+
   /**
-   * Mappign the staging buffer may take some time, so can delegate to a worker thread
+   * Mapping the staging buffer may take some time, so can delegate to a worker thread
    * if necessary.
    */
   Dali::SharedFuture InitializeTextureStagingBuffer(uint32_t size, bool useWorkerThread)
@@ -192,8 +243,7 @@ struct VulkanGraphicsController::Impl
     if(!mTextureStagingBuffer ||
        mTextureStagingBuffer->GetImpl()->GetSize() < size)
     {
-      auto workerFunc = [&, size](auto workerIndex)
-      {
+      auto workerFunc = [&, size](auto workerIndex) {
         Graphics::BufferCreateInfo createInfo{};
         createInfo.SetSize(size)
           .SetUsage(0u | Dali::Graphics::BufferUsage::TRANSFER_SRC);
@@ -283,8 +333,7 @@ struct VulkanGraphicsController::Impl
         }
         assert(image);
 
-        auto predicate = [&](auto& item) -> bool
-        {
+        auto predicate = [&](auto& item) -> bool {
           return image->GetVkHandle() == item.image.GetVkHandle();
         };
         auto it = std::find_if(requestMap.begin(), requestMap.end(), predicate);
@@ -504,6 +553,9 @@ struct VulkanGraphicsController::Impl
 
   ThreadPool mThreadPool;
 
+  DepthStencilFlags mDepthStencilBufferCurrentState{0u};
+  DepthStencilFlags mDepthStencilBufferRequestedState{0u};
+
   std::unordered_map<uint32_t, Graphics::UniquePtr<Graphics::Texture>> mExternalTextureResources;        ///< Used for ResourceId.
   std::queue<const Vulkan::Texture*>                                   mTextureMipmapGenerationRequests; ///< Queue for texture mipmap generation requests
 
@@ -670,8 +722,7 @@ void VulkanGraphicsController::UpdateTextures(
 
         if(destTexture->GetProperties().directWriteAccessEnabled)
         {
-          auto taskLambda = [pInfo, sourcePtr, sourceInfoPtr, texture](auto workerIndex)
-          {
+          auto taskLambda = [pInfo, sourcePtr, sourceInfoPtr, texture](auto workerIndex) {
             const auto& properties = texture->GetProperties();
 
             if(properties.emulated)
@@ -706,8 +757,7 @@ void VulkanGraphicsController::UpdateTextures(
           // The staging buffer is not allocated yet. The task knows pointer to the pointer which will point
           // at staging buffer right before executing tasks. The function will either perform direct copy
           // or will do suitable conversion if source format isn't supported and emulation is available.
-          auto taskLambda = [ppStagingMemory, currentOffset, pInfo, sourcePtr, texture](auto workerThread)
-          {
+          auto taskLambda = [ppStagingMemory, currentOffset, pInfo, sourcePtr, texture](auto workerThread) {
             char* pStagingMemory = reinterpret_cast<char*>(*ppStagingMemory);
 
             // Try to initialise` texture resources explicitly if they are not yet initialised
@@ -745,8 +795,7 @@ void VulkanGraphicsController::UpdateTextures(
   for(auto& item : updateMap)
   {
     auto pUpdates = &item.second;
-    auto task     = [pUpdates](auto workerIndex)
-    {
+    auto task     = [pUpdates](auto workerIndex) {
       for(auto& update : *pUpdates)
       {
         update.copyTask(workerIndex);
@@ -856,9 +905,14 @@ void VulkanGraphicsController::GenerateTextureMipmaps(const Graphics::Texture& t
 {
 }
 
-bool VulkanGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool enableStencil)
+bool VulkanGraphicsController::EnableDepthStencilBuffer(
+  const Graphics::RenderTarget& gfxRenderTarget,
+  bool                          enableDepth,
+  bool                          enableStencil)
 {
-  return true;
+  // if we enable depth/stencil dynamically we need to block and invalidate pipeline cache
+  auto renderTarget = static_cast<const Vulkan::RenderTarget*>(&gfxRenderTarget);
+  return mImpl->EnableDepthStencilBuffer(*renderTarget, enableDepth, enableStencil);
 }
 
 void VulkanGraphicsController::RunGarbageCollector(size_t numberOfDiscardedRenderers)
@@ -1149,7 +1203,7 @@ bool VulkanGraphicsController::HasClipMatrix() const
 const Matrix& VulkanGraphicsController::GetClipMatrix() const
 {
   constexpr float CLIP_MATRIX_DATA[] = {
-    1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f};
+    1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f};
   static const Matrix CLIP_MATRIX(CLIP_MATRIX_DATA);
   return CLIP_MATRIX;
 }
index 0e10695eb306e68e3ab21827f59d045b26cd0e12..bb04ac2a39bb77b878c19f04b481f4def2616ed8 100644 (file)
@@ -129,11 +129,12 @@ public:
   /**
    * @brief Enables depth/stencil buffer
    *
+   * @param[in] renderTarget The surface for which to enable depth/stencil buffer.
    * @param[in] enableDepth True to enable depth
    * @param[in] enableStencil True to enable stencil
    * @return True on success
    */
-  bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override;
+  bool EnableDepthStencilBuffer(const Graphics::RenderTarget& renderTarget, bool enableDepth, bool enableStencil) override;
 
   /**
    * @brief Runs garbage collector (if supported)
index 53d8302f9a46bc93b9c26fb042d7aa37dd55eb9a..0fb1360804ece1de613d093766e6706dea09d50b 100644 (file)
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef DALI_GRAPHICS_VULKAN_HANDLE_H
+#define DALI_GRAPHICS_VULKAN_HANDLE_H
 
 /*
  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
@@ -31,7 +32,7 @@ public:
 
   Handle& operator=(const Handle& handle);
 
-  Handle& operator=(Handle&& handle);
+  Handle& operator=(Handle&& handle) noexcept;
 
   Handle(Handle&& handle) noexcept;
 
@@ -44,7 +45,7 @@ public:
     return mObject;
   }
 
-  uint32_t GetRefCount() const
+  [[nodiscard]] uint32_t GetRefCount() const
   {
     return mObject->GetRefCount();
   }
@@ -134,7 +135,7 @@ Handle<T>::operator bool() const
 }
 
 template<class T>
-Handle<T>& Handle<T>::operator=(Handle&& handle)
+Handle<T>& Handle<T>::operator=(Handle&& handle) noexcept
 {
   if(mObject)
   {
@@ -148,10 +149,13 @@ Handle<T>& Handle<T>::operator=(Handle&& handle)
 template<class T>
 Handle<T>& Handle<T>::operator=(const Handle<T>& handle)
 {
-  mObject = handle.mObject;
-  if(mObject)
+  if(handle.mObject != this)
   {
-    mObject->Retain();
+    mObject = handle.mObject;
+    if(mObject)
+    {
+      mObject->Retain();
+    }
   }
   return *this;
 }
@@ -243,3 +247,5 @@ private:
 };
 
 } // namespace Dali::Graphics::Vulkan
+
+#endif // DALI_GRAPHICS_VULKAN_HANDLE_H
index dc9ea516fb32777bc377e349ad2c652248ce536d..0703f122a3c41f1a39aef840ccbfab7cd7f41a10 100644 (file)
@@ -24,7 +24,7 @@
 namespace Dali::Graphics::Vulkan
 {
 class Device;
-class Memory;
+class MemoryImpl;
 
 // @todo use ImageImpl to make naming convention consistent
 
@@ -152,7 +152,7 @@ public:
 
   [[nodiscard]] vk::SampleCountFlagBits GetSampleCount() const;
 
-  [[nodiscard]] MemoryImpl* GetMemory() const
+  [[nodiscard]] Vulkan::MemoryImpl* GetMemory() const
   {
     return mMemory.get();
   }
index 40a2fb72f6add92c059b8e72f571af3512fbfb64..86b434c868aa42770321e06647edeab4325193b5 100644 (file)
@@ -22,6 +22,7 @@
 
 namespace Dali::Graphics::Vulkan
 {
+
 class MemoryImpl
 {
 public:
index 03d928098d8f5b46bbad02f15f17430578f9231f..f6645ea1db5563278cd760c9582436b98f147aa6 100644 (file)
@@ -202,7 +202,7 @@ void PipelineImpl::Release()
 
 uint32_t PipelineImpl::GetRefCount() const
 {
-  return 0; //mRefCount;
+  return 0; // mRefCount;
 }
 
 PipelineImpl::~PipelineImpl() = default;
@@ -291,7 +291,10 @@ void PipelineImpl::InitializePipeline()
     if(gfxPipelineInfo.pColorBlendState)
     {
       auto attachmentCount = impl->GetAttachments().size();
-
+      if(impl->HasDepthAttachment())
+      {
+        attachmentCount--;
+      }
       if(attachmentCount != mBlendStateAttachments.size())
       {
         // Make sure array is 1
@@ -332,7 +335,8 @@ void PipelineImpl::InitializeVertexInputState(vk::PipelineVertexInputStateCreate
   std::transform(mCreateInfo.vertexInputState->bufferBindings.begin(),
                  mCreateInfo.vertexInputState->bufferBindings.end(),
                  std::back_inserter(bindings),
-                 [](const VertexInputState::Binding& in) -> vk::VertexInputBindingDescription {
+                 [](const VertexInputState::Binding& in) -> vk::VertexInputBindingDescription
+                 {
                    vk::VertexInputBindingDescription out;
                    out.setInputRate((in.inputRate == VertexInputRate::PER_VERTEX ? vk::VertexInputRate::eVertex : vk::VertexInputRate::eInstance));
                    out.setBinding(0u); // To be filled later using indices
@@ -350,7 +354,8 @@ void PipelineImpl::InitializeVertexInputState(vk::PipelineVertexInputStateCreate
   std::transform(mCreateInfo.vertexInputState->attributes.begin(),
                  mCreateInfo.vertexInputState->attributes.end(),
                  std::back_inserter(attrs),
-                 [](const VertexInputState::Attribute& in) -> vk::VertexInputAttributeDescription {
+                 [](const VertexInputState::Attribute& in) -> vk::VertexInputAttributeDescription
+                 {
                    vk::VertexInputAttributeDescription out;
                    out.setBinding(in.binding);
                    out.setLocation(in.location);
@@ -506,11 +511,11 @@ void PipelineImpl::InitializeRasterizationState(vk::PipelineRasterizationStateCr
 {
   auto gfxRastState = mCreateInfo.rasterizationState;
 
-  out.setFrontFace([gfxRastState]() {
-    return gfxRastState->frontFace == FrontFace::CLOCKWISE ? vk::FrontFace::eClockwise : vk::FrontFace::eCounterClockwise;
-  }());
+  out.setFrontFace([gfxRastState]()
+                   { return gfxRastState->frontFace == FrontFace::CLOCKWISE ? vk::FrontFace::eClockwise : vk::FrontFace::eCounterClockwise; }());
 
-  out.setPolygonMode([polygonMode = gfxRastState->polygonMode]() {
+  out.setPolygonMode([polygonMode = gfxRastState->polygonMode]()
+                     {
     switch(polygonMode)
     {
       case PolygonMode::FILL:
@@ -526,10 +531,10 @@ void PipelineImpl::InitializeRasterizationState(vk::PipelineRasterizationStateCr
         return vk::PolygonMode::ePoint;
       }
     }
-    return vk::PolygonMode{};
-  }());
+    return vk::PolygonMode{}; }());
 
-  out.setCullMode([cullMode = gfxRastState->cullMode]() -> vk::CullModeFlagBits {
+  out.setCullMode([cullMode = gfxRastState->cullMode]() -> vk::CullModeFlagBits
+                  {
     switch(cullMode)
     {
       case CullMode::NONE:
@@ -549,8 +554,7 @@ void PipelineImpl::InitializeRasterizationState(vk::PipelineRasterizationStateCr
         return vk::CullModeFlagBits::eFrontAndBack;
       }
     }
-    return {};
-  }());
+    return {}; }());
 
   out.setLineWidth(1.0f);         // Line with hardcoded to 1.0f
   out.setDepthClampEnable(false); // no depth clamp
@@ -573,6 +577,21 @@ bool PipelineImpl::InitializeDepthStencilState(vk::PipelineDepthStencilStateCrea
     out.setDepthCompareOp(ConvCompareOp(in->depthCompareOp));
     return true;
   }
+  else
+  {
+    // If we're not setting the following through the createInfo struct, they must instead
+    // come from command buffer commands.
+    mDynamicStates.emplace_back(vk::DynamicState::eDepthTestEnable);
+    mDynamicStates.emplace_back(vk::DynamicState::eDepthWriteEnable);
+    mDynamicStates.emplace_back(vk::DynamicState::eDepthCompareOp);
+    mDynamicStates.emplace_back(vk::DynamicState::eDepthBounds);
+    mDynamicStates.emplace_back(vk::DynamicState::eDepthBoundsTestEnable);
+    mDynamicStates.emplace_back(vk::DynamicState::eStencilTestEnable);
+    mDynamicStates.emplace_back(vk::DynamicState::eStencilOp);
+    mDynamicStates.emplace_back(vk::DynamicState::eStencilCompareMask);
+    mDynamicStates.emplace_back(vk::DynamicState::eStencilWriteMask);
+    mDynamicStates.emplace_back(vk::DynamicState::eStencilReference);
+  }
   return false;
 }
 
@@ -580,7 +599,8 @@ void PipelineImpl::InitializeColorBlendState(vk::PipelineColorBlendStateCreateIn
 {
   auto in = mCreateInfo.colorBlendState;
 
-  auto ConvLogicOp = [](LogicOp in) {
+  auto ConvLogicOp = [](LogicOp in)
+  {
     switch(in)
     {
       case LogicOp::CLEAR:
@@ -651,7 +671,8 @@ void PipelineImpl::InitializeColorBlendState(vk::PipelineColorBlendStateCreateIn
     return vk::LogicOp{};
   };
 
-  auto ConvBlendOp = [](BlendOp in) {
+  auto ConvBlendOp = [](BlendOp in)
+  {
     switch(in)
     {
       case BlendOp::ADD:
@@ -738,7 +759,8 @@ void PipelineImpl::InitializeColorBlendState(vk::PipelineColorBlendStateCreateIn
     return vk::BlendOp{};
   };
 
-  auto ConvBlendFactor = [](BlendFactor in) {
+  auto ConvBlendFactor = [](BlendFactor in)
+  {
     switch(in)
     {
       case BlendFactor::ZERO:
@@ -831,7 +853,7 @@ void PipelineImpl::InitializeColorBlendState(vk::PipelineColorBlendStateCreateIn
 
   att.setAlphaBlendOp(ConvBlendOp(in->alphaBlendOp));
   att.setBlendEnable(in->blendEnable);
-  //att.setColorWriteMask()
+  // att.setColorWriteMask()
   att.setColorBlendOp(ConvBlendOp(in->colorBlendOp));
   att.setColorWriteMask(vk::ColorComponentFlags(in->colorComponentWriteBits));
   att.setColorWriteMask(vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
index 9c5d9a3c3209b6dfa29e18804478c6e76933d44d..c3c0a6b6d72b3f82e878b2a8fea06f7246cc6ba8 100644 (file)
@@ -30,18 +30,19 @@ extern Debug::Filter* gVulkanFilter;
 namespace Dali::Graphics::Vulkan
 {
 RenderPassHandle RenderPassImpl::New(
-  Vulkan::Device&                            device,
-  const std::vector<FramebufferAttachment*>& colorAttachments,
-  FramebufferAttachment*                     depthAttachment)
+  Vulkan::Device&             device,
+  const SharedAttachments&    colorAttachments,
+  FramebufferAttachmentHandle depthAttachment)
 {
   auto renderPass = new RenderPassImpl(device, colorAttachments, depthAttachment);
   return RenderPassHandle(renderPass);
 }
 
-RenderPassImpl::RenderPassImpl(Vulkan::Device&                            device,
-                               const std::vector<FramebufferAttachment*>& colorAttachments,
-                               FramebufferAttachment*                     depthAttachment)
-: mGraphicsDevice(&device)
+RenderPassImpl::RenderPassImpl(Vulkan::Device&             device,
+                               const SharedAttachments&    colorAttachments,
+                               FramebufferAttachmentHandle depthAttachment)
+: mGraphicsDevice(&device),
+  mHasDepthAttachment(bool(depthAttachment))
 {
   CreateCompatibleCreateInfo(colorAttachments, depthAttachment);
   CreateRenderPass();
@@ -76,8 +77,8 @@ std::vector<vk::ImageView>& RenderPassImpl::GetAttachments()
 }
 
 void RenderPassImpl::CreateCompatibleCreateInfo(
-  const std::vector<FramebufferAttachment*>& colorAttachments,
-  FramebufferAttachment*                     depthAttachment)
+  const SharedAttachments&    colorAttachments,
+  FramebufferAttachmentHandle depthAttachment)
 {
   auto hasDepth = false;
   if(depthAttachment)
@@ -152,22 +153,30 @@ void RenderPassImpl::CreateCompatibleCreateInfo(
 
   // Creating 2 subpass dependencies using VK_SUBPASS_EXTERNAL to leverage the implicit image layout
   // transitions provided by the driver
+  vk::AccessFlags        accessMask(vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite);
+  vk::PipelineStageFlags stageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput);
+  if(hasDepth)
+  {
+    accessMask |= vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
+    stageMask |= vk::PipelineStageFlagBits::eEarlyFragmentTests;
+  }
+
   mCreateInfo.subpassDependencies = {
     vk::SubpassDependency{}
       .setSrcSubpass(VK_SUBPASS_EXTERNAL)
       .setDstSubpass(0)
       .setSrcStageMask(vk::PipelineStageFlagBits::eBottomOfPipe)
-      .setDstStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
+      .setDstStageMask(stageMask)
       .setSrcAccessMask(vk::AccessFlagBits::eMemoryRead)
-      .setDstAccessMask(vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite)
+      .setDstAccessMask(accessMask)
       .setDependencyFlags(vk::DependencyFlagBits::eByRegion),
 
     vk::SubpassDependency{}
       .setSrcSubpass(0)
       .setDstSubpass(VK_SUBPASS_EXTERNAL)
-      .setSrcStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
+      .setSrcStageMask(stageMask)
       .setDstStageMask(vk::PipelineStageFlagBits::eBottomOfPipe)
-      .setSrcAccessMask(vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite)
+      .setSrcAccessMask(accessMask)
       .setDstAccessMask(vk::AccessFlagBits::eMemoryRead)
       .setDependencyFlags(vk::DependencyFlagBits::eByRegion)};
 
index 571cffc0a7cbd4764053b816d6857e8b9bd8750b..2fe63d3d04ba6457c04047292d8073ef4b2933e2 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <dali/graphics-api/graphics-render-pass-create-info.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-attachment.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-handle.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
 #include <dali/public-api/common/vector-wrapper.h>
@@ -58,11 +59,11 @@ public:
     vk::RenderPassCreateInfo               createInfo;
   };
 
-  static RenderPassHandle New(Vulkan::Device&                            device,
-                              const std::vector<FramebufferAttachment*>& colorAttachments,
-                              FramebufferAttachment*                     depthAttachment);
+  static RenderPassHandle New(Vulkan::Device&             device,
+                              const SharedAttachments&    colorAttachments,
+                              FramebufferAttachmentHandle depthAttachment);
 
-  RenderPassImpl(Vulkan::Device& device, const std::vector<FramebufferAttachment*>& colorAttachments, FramebufferAttachment* depthAttachment);
+  RenderPassImpl(Vulkan::Device& device, const SharedAttachments& colorAttachments, FramebufferAttachmentHandle depthAttachment);
 
   ~RenderPassImpl();
 
@@ -72,6 +73,11 @@ public:
 
   std::vector<vk::ImageView>& GetAttachments();
 
+  bool HasDepthAttachment()
+  {
+    return mHasDepthAttachment;
+  }
+
   CreateInfo& GetCreateInfo()
   {
     return mCreateInfo;
@@ -79,8 +85,8 @@ public:
 
 private:
   void CreateCompatibleCreateInfo(
-    const std::vector<FramebufferAttachment*>& colorAttachments,
-    FramebufferAttachment*                     depthAttachment);
+    const SharedAttachments&    colorAttachments,
+    FramebufferAttachmentHandle depthAttachment);
 
   void CreateRenderPass();
 
@@ -89,6 +95,7 @@ private:
   CreateInfo                 mCreateInfo;
   vk::RenderPass             mVkRenderPass;
   std::vector<vk::ImageView> mAttachments{};
+  bool                       mHasDepthAttachment;
 };
 
 } // namespace Dali::Graphics::Vulkan
index 42a36deb0d3df7610a9306ff8ba525d95269c364..8f4f035584e312ece6985de1b5ea94dc42a4d397 100644 (file)
@@ -18,6 +18,7 @@
 // INTERNAL INCLUDES
 #include <dali/internal/graphics/vulkan-impl/vulkan-fence-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-image-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-image-view-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-surface-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-swapchain-impl.h>
@@ -212,7 +213,7 @@ void Swapchain::Destroy()
   }
 }
 
-void Swapchain::CreateFramebuffers()
+void Swapchain::CreateFramebuffers(FramebufferAttachmentHandle depthAttachment)
 {
   assert(mSwapchainKHR && "Needs a swapchain before creating framebuffers");
 
@@ -250,11 +251,11 @@ void Swapchain::CreateFramebuffers()
     colorImageView.reset(ImageView::NewFromImage(mGraphicsDevice, *colorImage));
 
     // A new color attachment for each framebuffer
-    OwnedAttachments attachments;
+    SharedAttachments attachments;
     attachments.emplace_back(FramebufferAttachment::NewColorAttachment(colorImageView,
                                                                        clearColor,
                                                                        true));
-    std::unique_ptr<FramebufferAttachment>                       depthAttachment;
+
     std::unique_ptr<FramebufferImpl, void (*)(FramebufferImpl*)> framebuffer(
       FramebufferImpl::New(mGraphicsDevice,
                            compatibleRenderPass,
@@ -429,70 +430,40 @@ void Swapchain::Invalidate()
 
 void Swapchain::SetDepthStencil(vk::Format depthStencilFormat)
 {
-#if 0
-  RefCountedFramebufferAttachment depthAttachment;
-  auto swapchainExtent = mSwapchainCreateInfoKHR.imageExtent;
+  FramebufferAttachmentHandle depthAttachment;
+  auto                        swapchainExtent = mSwapchainCreateInfoKHR.imageExtent;
 
-  if( depthStencilFormat != vk::Format::eUndefined )
+  if(depthStencilFormat != vk::Format::eUndefined)
   {
     // Create depth/stencil image
     auto imageCreateInfo = vk::ImageCreateInfo{}
-      .setFormat( depthStencilFormat )
-      .setMipLevels( 1 )
-      .setTiling( vk::ImageTiling::eOptimal )
-      .setImageType( vk::ImageType::e2D )
-      .setArrayLayers( 1 )
-      .setExtent( { swapchainExtent.width, swapchainExtent.height, 1 } )
-      .setUsage( vk::ImageUsageFlagBits::eDepthStencilAttachment )
-      .setSharingMode( vk::SharingMode::eExclusive )
-      .setInitialLayout( vk::ImageLayout::eUndefined )
-      .setSamples( vk::SampleCountFlagBits::e1 );
-
-    auto dsRefCountedImage = mGraphicsDevice->CreateImage( imageCreateInfo );
+                             .setFormat(depthStencilFormat)
+                             .setMipLevels(1)
+                             .setTiling(vk::ImageTiling::eOptimal)
+                             .setImageType(vk::ImageType::e2D)
+                             .setArrayLayers(1)
+                             .setExtent({swapchainExtent.width, swapchainExtent.height, 1})
+                             .setUsage(vk::ImageUsageFlagBits::eDepthStencilAttachment)
+                             .setSharingMode(vk::SharingMode::eExclusive)
+                             .setInitialLayout(vk::ImageLayout::eUndefined)
+                             .setSamples(vk::SampleCountFlagBits::e1);
 
-    auto memory = mGraphicsDevice->AllocateMemory( dsRefCountedImage, vk::MemoryPropertyFlagBits::eDeviceLocal );
+    mDepthStencilBuffer.reset(Image::New(mGraphicsDevice, imageCreateInfo));
 
-    mGraphics->BindImageMemory( dsRefCountedImage, std::move(memory), 0 );
+    mDepthStencilBuffer->AllocateAndBind(vk::MemoryPropertyFlagBits::eDeviceLocal);
 
     // create the depth stencil ImageView to be used within framebuffer
-    auto depthStencilImageView = ImageView::New(dsRefCountedImage);
-    auto depthClearValue = vk::ClearDepthStencilValue{}.setDepth( 0.0 )
-                                                       .setStencil( STENCIL_DEFAULT_CLEAR_VALUE );
+    auto depthStencilImageView = std::unique_ptr<ImageView>(ImageView::NewFromImage(mGraphicsDevice, *mDepthStencilBuffer));
+    auto depthClearValue       = vk::ClearDepthStencilValue{}.setDepth(0.0).setStencil(STENCIL_DEFAULT_CLEAR_VALUE);
 
-    // A single depth attachment for the swapchain.
-    depthAttachment = FramebufferAttachment::NewDepthAttachment( depthStencilImageView, depthClearValue );
-  }
-
-  // Get images
-  auto images = VkAssert( mGraphics->GetDevice().getSwapchainImagesKHR( mSwapchainKHR ) );
-
-  // allocate framebuffers
-  auto framebuffers = std::vector< RefCountedFramebuffer >{};
-  framebuffers.reserve( images.size() );
-
-  auto clearColor = vk::ClearColorValue{}.setFloat32( { 0.0f, 0.0f, 0.0f, 1.0f } );
-
-  for( auto&& image : images )
-  {
-    // @todo When do we kill this auto image & imageView? MemLeak.
-    auto colorImageView = ImageView::New( mGraphics->CreateImageFromExternal( image, mSwapchainCreateInfoKHR.imageFormat, swapchainExtent ) );
-
-    // A new color attachment for each framebuffer
-    auto colorAttachment = FramebufferAttachment::NewColorAttachment(colorImageView,
-                                                                     clearColor,
-                                                                     true);//presentable
-
-    framebuffers.push_back( mGraphics->CreateFramebuffer({colorAttachment},
-                                                         depthAttachment,
-                                                         swapchainExtent.width,
-                                                         swapchainExtent.height ) );
+    // A single depth attachment for the swapchain. Takes ownership of the image view
+    depthAttachment = FramebufferAttachmentHandle(FramebufferAttachment::NewDepthAttachment(depthStencilImageView, depthClearValue));
   }
 
   // Before replacing framebuffers in the swapchain, wait until all is done
-  mGraphics->DeviceWaitIdle();
+  mGraphicsDevice.DeviceWaitIdle();
 
-  mFramebuffers = std::move( framebuffers );
-#endif
+  CreateFramebuffers(depthAttachment);
 }
 
 uint32_t Swapchain::GetImageCount() const
index 92380475f2c581cf6111dada6126880de50ceaf5..b9b76c9a29b852f4c4df343f33ebcfaad2f76c86 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 // INTERNAL INCLUDES
+#include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-attachment.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
 
 namespace Dali::Graphics::Vulkan
@@ -28,7 +29,7 @@ class Device;
 class FenceImpl;
 class SurfaceImpl;
 class Queue;
-class SwapchainBuffer;
+struct SwapchainBuffer;
 
 /**
  * Creates swapchain for given surface and queue
@@ -56,8 +57,10 @@ public:
 
   /**
    * Automatically create framebuffers (generating compatible render passes)
+   *
+   * @param[in] depthAttachment Optional depth attachment.
    */
-  void CreateFramebuffers();
+  void CreateFramebuffers(FramebufferAttachmentHandle depthAttachment);
 
   [[nodiscard]] vk::SwapchainKHR GetVkHandle() const;
 
@@ -145,6 +148,7 @@ private:
    */
   using OwnedFramebuffer = std::unique_ptr<FramebufferImpl, void (*)(FramebufferImpl*)>;
   std::vector<OwnedFramebuffer> mFramebuffers;
+  std::unique_ptr<Image>        mDepthStencilBuffer;
 
   /**
    * Array of swapchain buffers
index c4dd38219f1ae2ce404a9a4a934f28c08b298b10..291d01f8221cd33d951ab920648da872ce8b7a81 100644 (file)
@@ -192,6 +192,76 @@ struct VkStoreOpType
   vk::AttachmentStoreOp storeOp{vk::AttachmentStoreOp::eDontCare};
 };
 
+struct VkCompareOpType
+{
+  constexpr explicit VkCompareOpType(Graphics::CompareOp compareOp)
+  {
+    switch(compareOp)
+    {
+      case Graphics::CompareOp::NEVER:
+        op = vk::CompareOp::eNever;
+        break;
+      case Graphics::CompareOp::LESS:
+        op = vk::CompareOp::eLess;
+        break;
+      case Graphics::CompareOp::EQUAL:
+        op = vk::CompareOp::eEqual;
+        break;
+      case Graphics::CompareOp::LESS_OR_EQUAL:
+        op = vk::CompareOp::eLessOrEqual;
+        break;
+      case Graphics::CompareOp::GREATER:
+        op = vk::CompareOp::eGreater;
+        break;
+      case Graphics::CompareOp::NOT_EQUAL:
+        op = vk::CompareOp::eNotEqual;
+        break;
+      case Graphics::CompareOp::GREATER_OR_EQUAL:
+        op = vk::CompareOp::eGreaterOrEqual;
+        break;
+      case Graphics::CompareOp::ALWAYS:
+        op = vk::CompareOp::eAlways;
+        break;
+    }
+  }
+  vk::CompareOp op{vk::CompareOp::eLess};
+};
+
+struct VkStencilOpType
+{
+  constexpr explicit VkStencilOpType(Graphics::StencilOp stencilOp)
+  {
+    switch(stencilOp)
+    {
+      case Graphics::StencilOp::KEEP:
+        op = vk::StencilOp::eKeep;
+        break;
+      case Graphics::StencilOp::ZERO:
+        op = vk::StencilOp::eZero;
+        break;
+      case Graphics::StencilOp::REPLACE:
+        op = vk::StencilOp::eReplace;
+        break;
+      case Graphics::StencilOp::INCREMENT_AND_CLAMP:
+        op = vk::StencilOp::eIncrementAndClamp;
+        break;
+      case Graphics::StencilOp::DECREMENT_AND_CLAMP:
+        op = vk::StencilOp::eDecrementAndClamp;
+        break;
+      case Graphics::StencilOp::INVERT:
+        op = vk::StencilOp::eInvert;
+        break;
+      case Graphics::StencilOp::INCREMENT_AND_WRAP:
+        op = vk::StencilOp::eIncrementAndWrap;
+        break;
+      case Graphics::StencilOp::DECREMENT_AND_WRAP:
+        op = vk::StencilOp::eDecrementAndWrap;
+        break;
+    }
+  }
+  vk::StencilOp op{vk::StencilOp::eZero};
+};
+
 } // namespace Vulkan
 } // namespace Dali::Graphics
 
index 98f22b9fa30f7d70ec662bd1405ef6505c4b2a0a..f751f37aa38b204943035bc17693cadb4bd2559b 100644 (file)
@@ -390,7 +390,8 @@ Swapchain* Device::CreateSwapchain(SurfaceImpl*       surface,
   }
 
   // @todo: Only create framebuffers if no "external" render passes.
-  newSwapchain->CreateFramebuffers(); // Note, this may destroy vk swapchain if invalid.
+  FramebufferAttachmentHandle empty;
+  newSwapchain->CreateFramebuffers(empty); // Note, this may destroy vk swapchain if invalid.
   return newSwapchain;
 }
 
@@ -591,9 +592,12 @@ uint32_t Device::GetCurrentBufferIndex() const
 void Device::CreateInstance(const std::vector<const char*>& extensions,
                             const std::vector<const char*>& validationLayers)
 {
-  auto info = vk::InstanceCreateInfo{};
-
-  info.setEnabledExtensionCount(U32(extensions.size()))
+  auto info    = vk::InstanceCreateInfo{};
+  auto appInfo = vk::ApplicationInfo{};
+  appInfo.setApiVersion(VK_API_VERSION_1_3);
+  info
+    .setPApplicationInfo(&appInfo)
+    .setEnabledExtensionCount(U32(extensions.size()))
     .setPpEnabledExtensionNames(extensions.data())
     .setEnabledLayerCount(U32(validationLayers.size()))
     .setPpEnabledLayerNames(validationLayers.data());
@@ -624,6 +628,7 @@ void Device::PreparePhysicalDevice(SurfaceImpl* surface)
 
   // if only one, pick first
   mPhysicalDevice = nullptr;
+  int gpuId       = 0;
   if(devices.size() == 1)
   {
     mPhysicalDevice = devices[0];
@@ -655,6 +660,11 @@ void Device::PreparePhysicalDevice(SurfaceImpl* surface)
           ++queueIndex;
         }
       }
+      if(mPhysicalDevice)
+      {
+        break;
+      }
+      gpuId++;
     }
   }
 
@@ -673,6 +683,8 @@ void Device::PreparePhysicalDevice(SurfaceImpl* surface)
                                VK_API_VERSION_PATCH(mPhysicalDeviceProperties.apiVersion),
                                (const char*)mPhysicalDeviceProperties.deviceName,
                                mPhysicalDeviceProperties.driverVersion);
+
+  DALI_LOG_INFO(gVulkanFilter, Debug::Concise, "GPU ID:%d\n", gpuId);
 }
 
 void Device::GetPhysicalDeviceProperties()
@@ -876,8 +888,7 @@ vk::Result Device::Submit(Queue& queue, const std::vector<SubmissionData>& submi
     std::transform(subData.commandBuffers.cbegin(),
                    subData.commandBuffers.cend(),
                    std::back_inserter(commandBufferHandles),
-                   [&](CommandBufferImpl* entry)
-                   {
+                   [&](CommandBufferImpl* entry) {
                      return entry->GetVkHandle();
                    });
 
index 04edf83097810d1aea4106f86ede8069c275b4fe..60a289ead40c16742df15f81d69c6dec8c86d4b0 100644 (file)
@@ -115,12 +115,6 @@ public: // Getters
 
   void DiscardResource(std::function<void()> deleter);
 
-  FramebufferImpl* CreateFramebuffer(const std::vector<FramebufferAttachment*>& colorAttachments,
-                                     FramebufferAttachment*                     depthAttachment,
-                                     uint32_t                                   width,
-                                     uint32_t                                   height,
-                                     RenderPassImpl*                            externalRenderPass = nullptr);
-
   Image* CreateImageFromExternal(vk::Image externalImage, vk::Format imageFormat, vk::Extent2D extent);
 
   uint32_t GetCurrentBufferIndex() const;