]> OCCT Git - occt-copy.git/commitdiff
0030631: Visualization - Vulkan graphic driver prototype CR30631_1
authorkgv <kgv@opencascade.com>
Thu, 4 Apr 2019 20:20:45 +0000 (23:20 +0300)
committerkgv <kgv@opencascade.com>
Sat, 13 Apr 2019 21:30:01 +0000 (00:30 +0300)
80 files changed:
adm/MODULES
adm/UDLIST
adm/cmake/occt_csf.cmake
adm/genproj.tcl
src/OS/Visualization.tcl
src/TKViewerTest/EXTERNLIB
src/TKVulkan/CMakeLists.txt [new file with mode: 0644]
src/TKVulkan/EXTERNLIB [new file with mode: 0644]
src/TKVulkan/FILES [new file with mode: 0644]
src/TKVulkan/PACKAGES [new file with mode: 0644]
src/ViewerTest/ViewerTest_ViewerCommands.cxx
src/Vulkan/FILES [new file with mode: 0644]
src/Vulkan/Vulkan_Buffer.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Buffer.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_Caps.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Caps.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_CommandBuffer.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_CommandBuffer.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_CommandPool.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_CommandPool.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_Context.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Context.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_DescriptorPool.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_DescriptorPool.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_DescriptorSetLayout.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_DescriptorSetLayout.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_Device.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Device.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_DeviceMemory.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_DeviceMemory.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_DeviceMemoryAllocator.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_DeviceMemoryAllocator.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_Fence.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Fence.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_ForwardDecl.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_FrameBuffer.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_FrameBuffer.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_FrameStats.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_FrameStats.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_GraphicDriver.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_GraphicDriver.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_Group.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Group.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_Image.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Image.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_Object.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Object.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_Pipeline.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Pipeline.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_PipelineCache.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_PipelineCache.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_PipelineLayout.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_PipelineLayout.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_PrimitiveArray.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_PrimitiveArray.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_RenderPass.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_RenderPass.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_Shader.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Shader.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderFlat.fs [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderFlat.vs [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderFlat_fs_spv.pxx [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderFlat_vs_spv.pxx [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderPhong.fs [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderPhong.vs [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderPhong_fs_spv.pxx [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderPhong_vs_spv.pxx [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderUnlit.fs [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderUnlit.vs [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderUnlit_fs_spv.pxx [new file with mode: 0644]
src/Vulkan/Vulkan_ShaderUnlit_vs_spv.pxx [new file with mode: 0644]
src/Vulkan/Vulkan_Structure.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Structure.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_StructureShadow.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_StructureShadow.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_Surface.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_Surface.hxx [new file with mode: 0644]
src/Vulkan/Vulkan_View.cxx [new file with mode: 0644]
src/Vulkan/Vulkan_View.hxx [new file with mode: 0644]
src/Vulkan/generate_spv.bat [new file with mode: 0644]

index e65fb379eedc8142d6764e4430c245f18238d066..82e10f8744ed879d985020f9ce23f1e731a6d34c 100644 (file)
@@ -1,7 +1,7 @@
 FoundationClasses TKernel TKMath
 ModelingData TKG2d TKG3d TKGeomBase TKBRep
 ModelingAlgorithms TKGeomAlgo TKTopAlgo TKPrim TKBO TKBool TKHLR TKFillet TKOffset TKFeat TKMesh TKXMesh TKShHealing
-Visualization TKService TKV3d TKOpenGl TKMeshVS TKIVtk TKD3DHost
+Visualization TKService TKV3d TKOpenGl TKMeshVS TKIVtk TKD3DHost TKVulkan
 ApplicationFramework TKCDF TKLCAF TKCAF TKBinL TKXmlL TKBin TKXml TKStdL TKStd TKTObj TKBinTObj TKXmlTObj TKVCAF
 DataExchange TKXSBase TKSTEPBase TKSTEPAttr TKSTEP209 TKSTEP TKIGES TKXCAF TKXDEIGES TKXDESTEP TKSTL TKVRML TKXmlXCAF TKBinXCAF
 Draw TKDraw TKTopTest TKViewerTest TKXSDRAW TKDCAF TKXDEDRAW TKTObjDRAW TKQADraw TKIVtkDraw DRAWEXE
index 0c6b6360d2351218664c5fc610310a7295bfd3a4..2ccee5aff6b10021ca5175332cd85600688922aa 100644 (file)
@@ -206,6 +206,7 @@ n Image
 n MeshVS
 n OpenGl
 n D3DHost
+n Vulkan
 n Prs3d
 n PrsMgr
 n Select3D
@@ -223,6 +224,7 @@ r Shaders
 t TKMeshVS
 t TKOpenGl
 t TKD3DHost
+t TKVulkan
 t TKService
 t TKV3d
 n BinTObjDrivers
index da796d18f71bb2ec5c2c5a82e2d8b2edf44bc3c4..09ec39282af39b8b12da0b77f855f475bdcaf5fa 100644 (file)
@@ -58,6 +58,9 @@ if (USE_TCL)
   endif()
 endif()
 
+# Vulkan
+set (CSF_vulkan "vulkan-1")
+
 if (WIN32)
   set (CSF_advapi32      "advapi32.lib")
   set (CSF_gdi32         "gdi32.lib")
index b51804ae941a244e58068d7bdfa4c64da335de8b..7e9d53f848fef9724704906f22f4bfdab587e743 100644 (file)
@@ -1349,6 +1349,8 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
     set aLibsMap(CSF_LIBLZMA) "liblzma"
   }
 
+  set aLibsMap(CSF_vulkan) "vulkan-1"
+
   if { "$theOS" == "wnt" } {
     #  WinAPI libraries
     set aLibsMap(CSF_kernel32)     "kernel32"
index 71885b3ccf2bdd0382f8c0d09d2e8b251ae61f37..5de72ea204d4686e59cadb1d629af7f0d3814b8a 100644 (file)
@@ -18,6 +18,7 @@ proc Visualization:toolkits { } {
     set aResult [list TKService \
                      TKV3d \
                      TKOpenGl \
+                     TKVulkan \
                      TKMeshVS]
 
     if { [info exists ::env(HAVE_VTK)] && "$::env(HAVE_VTK)" == "true" } {
index 9181318b9306346f1d44b65bfa93c89646e28aa0..475712cbebc2a9b6344c59c094310f0c4b4dac96 100755 (executable)
@@ -18,6 +18,7 @@ TKMesh
 TKV3d
 TKDraw
 TKOpenGl
+TKVulkan
 CSF_TclLibs
 CSF_TclTkLibs
 CSF_XwLibs
diff --git a/src/TKVulkan/CMakeLists.txt b/src/TKVulkan/CMakeLists.txt
new file mode 100644 (file)
index 0000000..89337e5
--- /dev/null
@@ -0,0 +1,3 @@
+project(TKVulkan)
+
+OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit)
diff --git a/src/TKVulkan/EXTERNLIB b/src/TKVulkan/EXTERNLIB
new file mode 100644 (file)
index 0000000..6684eca
--- /dev/null
@@ -0,0 +1,13 @@
+TKernel
+TKService
+TKMath
+TKV3d
+CSF_TBB
+CSF_FREETYPE
+CSF_vulkan
+CSF_user32
+CSF_gdi32
+CSF_XwLibs
+CSF_Appkit
+CSF_IOKit
+CSF_objc
diff --git a/src/TKVulkan/FILES b/src/TKVulkan/FILES
new file mode 100644 (file)
index 0000000..ca4f0e5
--- /dev/null
@@ -0,0 +1,2 @@
+EXTERNLIB
+PACKAGES
diff --git a/src/TKVulkan/PACKAGES b/src/TKVulkan/PACKAGES
new file mode 100644 (file)
index 0000000..7357e85
--- /dev/null
@@ -0,0 +1 @@
+Vulkan
index 0d1b955a8e71603f8ff22ed8838be1ba836a66b2..3533191c961cafc67c8ec87579619d27ed0dbc7e 100644 (file)
@@ -83,6 +83,9 @@
 #include <Prs3d_Text.hxx>
 #include <Select3D_SensitivePrimitiveArray.hxx>
 
+#include <Vulkan_Caps.hxx>
+#include <Vulkan_GraphicDriver.hxx>
+
 #ifdef _WIN32
 #undef DrawText
 #endif
@@ -718,7 +721,7 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft
     theViewToClone->Window()->Size (aPxWidth, aPxHeight);
   }
 
-  Handle(OpenGl_GraphicDriver) aGraphicDriver;
+  Handle(Graphic3d_GraphicDriver) aGraphicDriver;
   ViewerTest_Names aViewNames(theViewName);
   if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ()))
     aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
@@ -765,15 +768,29 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft
       // alternatively we can disable buffer swap at all, but this might be inappropriate for testing
       //ViewerTest_myDefaultCaps.buffersNoSwap = true;
     }
-    aGraphicDriver = new OpenGl_GraphicDriver (GetDisplayConnection());
-    aGraphicDriver->ChangeOptions() = ViewerTest_myDefaultCaps;
+
+    if (theDisplayName == "vulkan")
+    {
+      /// TODO
+      const uint32_t anAppVer = Vulkan_GraphicDriver::DefineVersion (OCC_VERSION_MAJOR, OCC_VERSION_MINOR, OCC_VERSION_MAINTENANCE);
+      Handle(Vulkan_GraphicDriver) aVkDriver = new Vulkan_GraphicDriver ("Draw Harness", anAppVer, GetDisplayConnection());
+      aVkDriver->Options()->contextDebug = true;
+      //aVkDriver->Options()->contextDebug = ViewerTest_myDefaultCaps.contextDebug;
+      aGraphicDriver = aVkDriver;
+    }
+    else
+    {
+      Handle(OpenGl_GraphicDriver) aGlDriver = new OpenGl_GraphicDriver (GetDisplayConnection());
+      aGlDriver->ChangeOptions() = ViewerTest_myDefaultCaps;
+      aGraphicDriver = aGlDriver;
+    }
 
     ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
     toCreateViewer = Standard_True;
   }
   else
   {
-    aGraphicDriver = Handle(OpenGl_GraphicDriver)::DownCast (ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName()));
+    aGraphicDriver = ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName());
   }
 
   //Dispose the window if input parameters are default
@@ -1108,7 +1125,7 @@ static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const cha
 #if defined(_WIN32) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
   if (!aDisplayName.IsEmpty())
   {
-    aDisplayName.Clear();
+    ////aDisplayName.Clear();
     std::cout << "Warning: display parameter will be ignored.\n";
   }
 #endif
@@ -12710,6 +12727,23 @@ static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
   return 0;
 }
 
+//===============================================================================================
+//function : VkInit
+//purpose  :
+//===============================================================================================
+static int VkInit (Draw_Interpretor& ,
+                   Standard_Integer  theArgsNb,
+                   const char**      theArgVec)
+{
+  (void )theArgsNb;
+  (void )theArgVec;
+  Handle(Aspect_DisplayConnection) aDisp = new Aspect_DisplayConnection();
+  const uint32_t anAppVer = Vulkan_GraphicDriver::DefineVersion (OCC_VERSION_MAJOR, OCC_VERSION_MINOR, OCC_VERSION_MAINTENANCE);
+  Handle(Vulkan_GraphicDriver) aDriver = new Vulkan_GraphicDriver ("Draw Harness", anAppVer, aDisp);
+  aDriver->InitContext();
+  return 0;
+}
+
 //=======================================================================
 //function : ViewerCommands
 //purpose  :
@@ -12719,6 +12753,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
 {
 
   const char *group = "ZeViewer";
+
+theCommands.Add("vkinit", "vkinit", __FILE__,VkInit,group); ///
+
   theCommands.Add("vinit",
           "vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]"
     "\n\t\t:     [-exitOnClose] [-closeOnEscape] [-cloneActive] [-2d_mode {on|off}=off]"
diff --git a/src/Vulkan/FILES b/src/Vulkan/FILES
new file mode 100644 (file)
index 0000000..ac8cc9b
--- /dev/null
@@ -0,0 +1,57 @@
+Vulkan_Buffer.cxx
+Vulkan_Buffer.hxx
+Vulkan_Caps.cxx
+Vulkan_Caps.hxx
+Vulkan_CommandBuffer.cxx
+Vulkan_CommandBuffer.hxx
+Vulkan_CommandPool.cxx
+Vulkan_CommandPool.hxx
+Vulkan_Context.cxx
+Vulkan_Context.hxx
+Vulkan_DescriptorPool.cxx
+Vulkan_DescriptorPool.hxx
+Vulkan_DescriptorSetLayout.cxx
+Vulkan_DescriptorSetLayout.hxx
+Vulkan_Device.cxx
+Vulkan_Device.hxx
+Vulkan_DeviceMemory.cxx
+Vulkan_DeviceMemory.hxx
+Vulkan_DeviceMemoryAllocator.cxx
+Vulkan_DeviceMemoryAllocator.hxx
+Vulkan_Fence.cxx
+Vulkan_Fence.hxx
+Vulkan_FrameBuffer.cxx
+Vulkan_FrameBuffer.hxx
+Vulkan_FrameStats.cxx
+Vulkan_FrameStats.hxx
+Vulkan_ForwardDecl.hxx
+Vulkan_GraphicDriver.cxx
+Vulkan_GraphicDriver.hxx
+Vulkan_Group.cxx
+Vulkan_Group.hxx
+Vulkan_Image.cxx
+Vulkan_Image.hxx
+Vulkan_Object.cxx
+Vulkan_Object.hxx
+Vulkan_Pipeline.cxx
+Vulkan_Pipeline.hxx
+Vulkan_PipelineCache.cxx
+Vulkan_PipelineCache.hxx
+Vulkan_PipelineLayout.cxx
+Vulkan_PipelineLayout.hxx
+Vulkan_PrimitiveArray.cxx
+Vulkan_PrimitiveArray.hxx
+Vulkan_RenderPass.cxx
+Vulkan_RenderPass.hxx
+Vulkan_Structure.cxx
+Vulkan_Structure.hxx
+Vulkan_StructureShadow.cxx
+Vulkan_StructureShadow.hxx
+Vulkan_Shader.cxx
+Vulkan_Shader.hxx
+Vulkan_Surface.cxx
+Vulkan_Surface.hxx
+Vulkan_View.cxx
+Vulkan_View.hxx
+Vulkan_Window.cxx
+Vulkan_Window.hxx
diff --git a/src/Vulkan/Vulkan_Buffer.cxx b/src/Vulkan/Vulkan_Buffer.cxx
new file mode 100644 (file)
index 0000000..f19914f
--- /dev/null
@@ -0,0 +1,170 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_Buffer.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_DeviceMemory.hxx>
+#include <Vulkan_DeviceMemoryAllocator.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Buffer, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_Buffer
+// purpose  :
+// =======================================================================
+Vulkan_Buffer::Vulkan_Buffer()
+: myVkBuffer (NULL),
+  mySize (0)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_Buffer
+// purpose  :
+// =======================================================================
+Vulkan_Buffer::~Vulkan_Buffer()
+{
+  releaseBuffer();
+}
+
+// =======================================================================
+// function : releaseBuffer
+// purpose  :
+// =======================================================================
+void Vulkan_Buffer::releaseBuffer()
+{
+  mySize = 0;
+  if (myVkBuffer != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_Buffer");
+    vkDestroyBuffer (myDevice->Device(), myVkBuffer, myDevice->HostAllocator());
+    myVkBuffer = NULL;
+  }
+  if (!myDevMemory.IsNull())
+  {
+    myDevMemory.Nullify();
+  }
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_Buffer::Create (const Handle(Vulkan_Device)& theDevice,
+                            Standard_Size theSize,
+                            Vulkan_BufferType theType)
+{
+  if (myVkBuffer != NULL
+   && mySize == theSize
+   && myDevice == theDevice)
+  {
+    return true;
+  }
+
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+
+  VkBufferCreateInfo aVkBuffInfo;
+  aVkBuffInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+  aVkBuffInfo.pNext = NULL;
+  aVkBuffInfo.flags = 0;
+  aVkBuffInfo.size = theSize;
+  aVkBuffInfo.usage = 0;
+  aVkBuffInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+  aVkBuffInfo.queueFamilyIndexCount = 0;
+  aVkBuffInfo.pQueueFamilyIndices = NULL;
+  switch (theType)
+  {
+    case Vulkan_BufferType_Uniform: aVkBuffInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; break;
+    case Vulkan_BufferType_Vertex:  aVkBuffInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;  break;
+    case Vulkan_BufferType_Index:   aVkBuffInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;   break;
+  }
+
+  VkResult aRes = vkCreateBuffer (theDevice->Device(), &aVkBuffInfo, theDevice->HostAllocator(), &myVkBuffer);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create buffer", aRes);
+    return false;
+  }
+
+  mySize = theSize;
+  return true;
+}
+
+// =======================================================================
+// function : init
+// purpose  :
+// =======================================================================
+bool Vulkan_Buffer::init (const Handle(Vulkan_Device)& theDevice,
+                          const void* theData,
+                          Standard_Size theNbBytes,
+                          Vulkan_BufferType theType)
+{
+  if (!Create (theDevice, theNbBytes, theType))
+  {
+    return false;
+  }
+
+  const bool toAllocMemory = myDevMemory.IsNull();
+  if (toAllocMemory)
+  {
+    VkMemoryRequirements aVkMemReqs = {};
+    vkGetBufferMemoryRequirements (theDevice->Device(), myVkBuffer, &aVkMemReqs);
+    myDevMemory = theDevice->DeviceMemoryAllocator()->Allocate (aVkMemReqs, Vulkan_DeviceMemoryUsage_CpuToGpu);
+    if (myDevMemory.IsNull())
+    {
+      Release();
+      return false;
+    }
+  }
+
+  if (theData != NULL)
+  {
+    void* aDataPtr = NULL;
+    const Vulkan_DeviceMemoryInfo aMemInfo = myDevMemory->DeviceMemoryInfo();
+    VkResult aRes = vkMapMemory (theDevice->Device(), aMemInfo.DeviceMemory, aMemInfo.Offset, theNbBytes, 0, &aDataPtr);
+    if (aRes != VK_SUCCESS)
+    {
+      logFailureAndRelease ("failed to map device memory", aRes);
+      return false;
+    }
+    memcpy (aDataPtr, theData, theNbBytes);
+    vkUnmapMemory (theDevice->Device(), aMemInfo.DeviceMemory);
+  }
+
+  if (toAllocMemory)
+  {
+    const Vulkan_DeviceMemoryInfo aMemInfo = myDevMemory->DeviceMemoryInfo();
+    VkResult aRes = vkBindBufferMemory (theDevice->Device(), myVkBuffer, aMemInfo.DeviceMemory, aMemInfo.Offset);
+    if (aRes != VK_SUCCESS)
+    {
+      logFailureAndRelease ("failed to bind buffer memory", aRes);
+      return false;
+    }
+  }
+
+  return true;
+}
diff --git a/src/Vulkan/Vulkan_Buffer.hxx b/src/Vulkan/Vulkan_Buffer.hxx
new file mode 100644 (file)
index 0000000..f0cce58
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Buffer_HeaderFile
+#define _Vulkan_Buffer_HeaderFile
+
+#include <Graphic3d_Vec.hxx>
+#include <Vulkan_Object.hxx>
+
+class Vulkan_DeviceMemory;
+
+enum Vulkan_BufferType
+{
+  Vulkan_BufferType_Uniform, //!< VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
+  Vulkan_BufferType_Vertex,  //!< VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
+  Vulkan_BufferType_Index,   //!< VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
+};
+
+//! This class defines an Vulkan buffer.
+class Vulkan_Buffer : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Buffer, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_Buffer();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_Buffer();
+
+  //! Return object.
+  VkBuffer Buffer() const { return myVkBuffer; }
+
+  //! Create the object, @sa vkCreateBuffer().
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice,
+                               Standard_Size theSize,
+                               Vulkan_BufferType theType);
+
+  //! Init the object.
+  bool Init (const Handle(Vulkan_Device)& theDevice,
+             const Graphic3d_Vec2* theData,
+             Standard_Size theLen)
+  {
+    const Standard_Size aSize = sizeof(*theData) * theLen;
+    return init (theDevice, theData, aSize, Vulkan_BufferType_Vertex);
+  }
+
+  //! Init the object.
+  bool Init (const Handle(Vulkan_Device)& theDevice,
+             const Graphic3d_Vec3* theData,
+             Standard_Size theLen)
+  {
+    const Standard_Size aSize = sizeof(*theData) * theLen;
+    return init (theDevice, theData, aSize, Vulkan_BufferType_Vertex);
+  }
+
+//protected:
+
+  //! Init the object.
+  Standard_EXPORT bool init (const Handle(Vulkan_Device)& theDevice,
+                             const void* theData,
+                             Standard_Size theNbBytes,
+                             Vulkan_BufferType theType);
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releaseBuffer(); }
+
+  //! Release the object, @sa vkDestroyBuffer().
+  Standard_EXPORT void releaseBuffer();
+
+protected:
+
+  Handle(Vulkan_DeviceMemory) myDevMemory;
+  VkBuffer       myVkBuffer;
+  Standard_Size  mySize;
+
+};
+
+#endif // _Vulkan_Buffer_HeaderFile
diff --git a/src/Vulkan/Vulkan_Caps.cxx b/src/Vulkan/Vulkan_Caps.cxx
new file mode 100644 (file)
index 0000000..2af26d8
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_Caps.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Caps, Standard_Transient)
+
+// =======================================================================
+// function : Vulkan_Caps
+// purpose  :
+// =======================================================================
+Vulkan_Caps::Vulkan_Caps()
+: swapInterval      (1),
+  buffersNoSwap     (Standard_False),
+#ifdef OCCT_DEBUG
+  contextDebug      (Standard_True),
+#else
+  contextDebug      (Standard_False),
+#endif
+  contextNoAccel    (Standard_False),
+  glslWarnings      (Standard_False),
+  suppressExtraMsg  (Standard_True)
+{
+  //
+}
+
+// =======================================================================
+// function : operator=
+// purpose  :
+// =======================================================================
+Vulkan_Caps& Vulkan_Caps::operator= (const Vulkan_Caps& theCopy)
+{
+  swapInterval      = theCopy.swapInterval;
+  buffersNoSwap     = theCopy.buffersNoSwap;
+  contextDebug      = theCopy.contextDebug;
+  contextNoAccel    = theCopy.contextNoAccel;
+  contextDevice     = theCopy.contextDevice;
+  glslWarnings      = theCopy.glslWarnings;
+  suppressExtraMsg  = theCopy.suppressExtraMsg;
+  return *this;
+}
+
+// =======================================================================
+// function : ~Vulkan_Caps
+// purpose  :
+// =======================================================================
+Vulkan_Caps::~Vulkan_Caps()
+{
+  //
+}
diff --git a/src/Vulkan/Vulkan_Caps.hxx b/src/Vulkan/Vulkan_Caps.hxx
new file mode 100644 (file)
index 0000000..a4eb62e
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Caps_HeaderFile
+#define _Vulkan_Caps_HeaderFile
+
+#include <Standard_Type.hxx>
+#include <Standard_Transient.hxx>
+#include <TCollection_AsciiString.hxx>
+
+//! Class to define graphic driver capabilities.
+//! Notice that these options will be ignored if particular functionality does not provided by Vulkan driver
+class Vulkan_Caps : public Standard_Transient
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Caps, Standard_Transient)
+public: //! @name flags to disable particular functionality, should be used only for testing purposes!
+
+  Standard_Integer swapInterval;      //!< controls swap interval - 0 for VSync off and 1 for VSync on, 1 by default
+
+public: //! @name context creation parameters
+
+  //! Specify that driver should not swap back/front buffers at the end of frame.
+  //! Useful when OCCT Viewer is integrated into existing Vulkan rendering pipeline as part,
+  //! thus swapping part is performed outside.
+  //!
+  //! OFF by default.
+  Standard_Boolean buffersNoSwap;
+
+  //! Request debug Vulkan context. This flag requires support of necessary layers in Vulkan driver.
+  //!
+  //! When turned on Vulkan driver emits error and warning messages to provided callback.
+  //! Affects performance - thus should not be turned on by products in released state.
+  //!
+  //! OFF by default.
+  Standard_Boolean contextDebug;
+
+  //! Disable hardware acceleration.
+  //!
+  //! Flags to intentionally look for VK_PHYSICAL_DEVICE_TYPE_CPU devices.
+  //!
+  //! OFF by default.
+  Standard_Boolean contextNoAccel;
+
+  //! Look for device with specified name.
+  //!
+  //! EMPTY by default.
+  TCollection_AsciiString contextDevice;
+
+public: //! @name flags to activate verbose output
+
+  //! Print GLSL program compilation/linkage warnings, if any. OFF by default.
+  Standard_Boolean glslWarnings;
+
+  //! Suppress redundant messages from debug Vulkan context. ON by default.
+  Standard_Boolean suppressExtraMsg;
+
+public: //! @name class methods
+
+  //! Default constructor - initialize with most optimal values.
+  Standard_EXPORT Vulkan_Caps();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_Caps();
+
+  //! Copy maker.
+  Standard_EXPORT Vulkan_Caps& operator= (const Vulkan_Caps& theCopy);
+
+private:
+
+  //! Not implemented
+  Vulkan_Caps (const Vulkan_Caps& );
+
+};
+
+#endif // _Vulkan_Caps_HeaderFile
diff --git a/src/Vulkan/Vulkan_CommandBuffer.cxx b/src/Vulkan/Vulkan_CommandBuffer.cxx
new file mode 100644 (file)
index 0000000..e201ea1
--- /dev/null
@@ -0,0 +1,235 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_CommandBuffer.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_CommandPool.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_FrameBuffer.hxx>
+#include <Vulkan_Pipeline.hxx>
+#include <Vulkan_RenderPass.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_CommandBuffer, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_CommandBuffer
+// purpose  :
+// =======================================================================
+Vulkan_CommandBuffer::Vulkan_CommandBuffer()
+: myVkCmdBuffer (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_CommandBuffer
+// purpose  :
+// =======================================================================
+Vulkan_CommandBuffer::~Vulkan_CommandBuffer()
+{
+  releaseBuffer();
+}
+
+// =======================================================================
+// function : releaseBuffer
+// purpose  :
+// =======================================================================
+void Vulkan_CommandBuffer::releaseBuffer()
+{
+  if (myVkCmdBuffer != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_CommandBuffer");
+    vkFreeCommandBuffers (myDevice->Device(), myCmdPool->CommandPool(), 1, &myVkCmdBuffer);
+    myVkCmdBuffer = NULL;
+  }
+  myCmdPool.Nullify();
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_CommandBuffer::Create (const Handle(Vulkan_CommandPool)& thePool)
+{
+  if (thePool.IsNull()
+   || thePool->CommandPool() == NULL)
+  {
+    Release();
+    return false;
+  }
+
+  if (myVkCmdBuffer != NULL
+   && myCmdPool == thePool)
+  {
+    return true;
+  }
+
+  Release();
+  myDevice = thePool->Device();
+  myCmdPool = thePool;
+
+  VkCommandBufferAllocateInfo anAllocInfo;
+  anAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+  anAllocInfo.pNext = NULL;
+  anAllocInfo.commandPool = myCmdPool->CommandPool();
+  anAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+  anAllocInfo.commandBufferCount = 1;
+
+  VkResult aRes = vkAllocateCommandBuffers (myDevice->Device(), &anAllocInfo, &myVkCmdBuffer);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to allocate command buffers", aRes);
+    return false;
+  }
+
+  aRes = vkResetCommandBuffer (myVkCmdBuffer, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to reset command buffer", aRes);
+    return false;
+  }
+
+  return true;
+}
+
+// =======================================================================
+// function : ResetCommandBuffer
+// purpose  :
+// =======================================================================
+bool Vulkan_CommandBuffer::ResetCommandBuffer()
+{
+  if (myVkCmdBuffer == NULL)
+  {
+    return false;
+  }
+
+  VkResult aRes = vkResetCommandBuffer (myVkCmdBuffer, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailure ("failed to reset command buffer", aRes);
+    return false;
+  }
+  return true;
+}
+
+// =======================================================================
+// function : BeginCommandBuffer
+// purpose  :
+// =======================================================================
+void Vulkan_CommandBuffer::BeginCommandBuffer (const Handle(Vulkan_RenderPass)& theRenderPass,
+                                               const Handle(Vulkan_FrameBuffer)& theFrameBuffer)
+{
+  VkCommandBufferInheritanceInfo anInherInfo;
+  anInherInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+  anInherInfo.pNext = NULL;
+  anInherInfo.renderPass = theRenderPass->RenderPass();
+  anInherInfo.subpass = 0;
+  anInherInfo.framebuffer = theFrameBuffer->FrameBuffer();
+  anInherInfo.occlusionQueryEnable = VK_FALSE;
+  anInherInfo.queryFlags = 0;
+  anInherInfo.pipelineStatistics = 0;
+
+  VkCommandBufferBeginInfo aBuffBeginInfo;
+  aBuffBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+  aBuffBeginInfo.pNext = NULL;
+  aBuffBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+  aBuffBeginInfo.pInheritanceInfo = &anInherInfo;
+
+  vkBeginCommandBuffer (myVkCmdBuffer, &aBuffBeginInfo);
+}
+
+// =======================================================================
+// function : EndCommandBuffer
+// purpose  :
+// =======================================================================
+void Vulkan_CommandBuffer::EndCommandBuffer()
+{
+  if (myVkCmdBuffer != NULL)
+  {
+    vkEndCommandBuffer (myVkCmdBuffer);
+  }
+}
+
+// =======================================================================
+// function : BeginRenderPass
+// purpose  :
+// =======================================================================
+void Vulkan_CommandBuffer::BeginRenderPass (const Handle(Vulkan_RenderPass)& theRenderPass,
+                                            const Handle(Vulkan_FrameBuffer)& theFrameBuffer,
+                                            const Graphic3d_Vec2u& theSize,
+                                            const Graphic3d_Vec4* theClearColor)
+{
+  if (myVkCmdBuffer == NULL)
+  {
+    return;
+  }
+
+  uint32_t aNbClears = 0;
+  VkClearValue aClearValues[2];
+  if (theClearColor != NULL)
+  {
+    aClearValues[aNbClears].color.float32[0] = theClearColor->r();
+    aClearValues[aNbClears].color.float32[1] = theClearColor->g();
+    aClearValues[aNbClears].color.float32[2] = theClearColor->b();
+    aClearValues[aNbClears].color.float32[3] = theClearColor->a();
+    ++aNbClears;
+  }
+  {
+    aClearValues[aNbClears].depthStencil.depth   = 1.0f;
+    aClearValues[aNbClears].depthStencil.stencil = 0;
+    ++aNbClears;
+  }
+
+  VkRenderPassBeginInfo aPassBeginInfo;
+  aPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+  aPassBeginInfo.pNext = NULL;
+  aPassBeginInfo.renderPass  = theRenderPass->RenderPass();
+  aPassBeginInfo.framebuffer = theFrameBuffer->FrameBuffer();
+  aPassBeginInfo.renderArea = VkRect2D{
+    VkOffset2D{0, 0},
+    VkExtent2D{theSize.x(), theSize.y()}
+  };
+  aPassBeginInfo.clearValueCount = aNbClears;
+  aPassBeginInfo.pClearValues = aClearValues;
+
+  vkCmdBeginRenderPass (myVkCmdBuffer, &aPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+}
+
+// =======================================================================
+// function : EndRenderPass
+// purpose  :
+// =======================================================================
+void Vulkan_CommandBuffer::EndRenderPass()
+{
+  if (myVkCmdBuffer != NULL)
+  {
+    vkCmdEndRenderPass (myVkCmdBuffer);
+  }
+}
+
+// =======================================================================
+// function : BindPipeline
+// purpose  :
+// =======================================================================
+void Vulkan_CommandBuffer::BindPipeline (const Handle(Vulkan_Pipeline)& thePipeline)
+{
+  if (myVkCmdBuffer != NULL)
+  {
+    vkCmdBindPipeline (myVkCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, thePipeline->Pipeline());
+  }
+}
diff --git a/src/Vulkan/Vulkan_CommandBuffer.hxx b/src/Vulkan/Vulkan_CommandBuffer.hxx
new file mode 100644 (file)
index 0000000..231b600
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_CommandBuffer_HeaderFile
+#define _Vulkan_CommandBuffer_HeaderFile
+
+#include <Graphic3d_Vec.hxx>
+#include <Vulkan_Object.hxx>
+
+class Vulkan_CommandPool;
+class Vulkan_FrameBuffer;
+class Vulkan_Pipeline;
+class Vulkan_RenderPass;
+
+//! This class defines an Vulkan command buffer.
+class Vulkan_CommandBuffer : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_CommandBuffer, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_CommandBuffer();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_CommandBuffer();
+
+  //! Return object.
+  const VkCommandBuffer& CommandBuffer() const { return myVkCmdBuffer; }
+
+  //! Create the object, @sa vkAllocateCommandBuffers().
+  Standard_EXPORT bool Create (const Handle(Vulkan_CommandPool)& thePool);
+
+  //! Reset commands in this buffer, @sa vkResetCommandBuffer().
+  Standard_EXPORT bool ResetCommandBuffer();
+
+  //! Begin writing command buffer, @sa vkBeginCommandBuffer().
+  Standard_EXPORT void BeginCommandBuffer (const Handle(Vulkan_RenderPass)& theRenderPass,
+                                           const Handle(Vulkan_FrameBuffer)& theFrameBuffer);
+
+  //! End writing command buffer, @sa vkEndCommandBuffer().
+  Standard_EXPORT void EndCommandBuffer();
+
+  //! Begin render pass, @sa vkCmdBeginRenderPass().
+  Standard_EXPORT void BeginRenderPass (const Handle(Vulkan_RenderPass)& theRenderPass,
+                                        const Handle(Vulkan_FrameBuffer)& theFrameBuffer,
+                                        const Graphic3d_Vec2u& theSize,
+                                        const Graphic3d_Vec4* theClearColor);
+
+  //! End render pass, @sa vkCmdEndRenderPass().
+  Standard_EXPORT void EndRenderPass();
+
+  //! Bind the pipeline, @sa vkCmdBindPipeline().
+  Standard_EXPORT void BindPipeline (const Handle(Vulkan_Pipeline)& thePipeline);
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releaseBuffer(); }
+
+  //! Release the object, @sa vkFreeCommandBuffers().
+  Standard_EXPORT void releaseBuffer();
+
+protected:
+
+  Handle(Vulkan_CommandPool) myCmdPool;
+  VkCommandBuffer myVkCmdBuffer;
+
+};
+
+#endif // _Vulkan_CommandBuffer_HeaderFile
diff --git a/src/Vulkan/Vulkan_CommandPool.cxx b/src/Vulkan/Vulkan_CommandPool.cxx
new file mode 100644 (file)
index 0000000..78463c6
--- /dev/null
@@ -0,0 +1,132 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_CommandPool.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_CommandBuffer.hxx>
+#include <Vulkan_Device.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_CommandPool, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_CommandPool
+// purpose  :
+// =======================================================================
+Vulkan_CommandPool::Vulkan_CommandPool()
+: myVkCmdPool (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_CommandPool
+// purpose  :
+// =======================================================================
+Vulkan_CommandPool::~Vulkan_CommandPool()
+{
+  releasePool();
+}
+
+// =======================================================================
+// function : releasePool
+// purpose  :
+// =======================================================================
+void Vulkan_CommandPool::releasePool()
+{
+  if (myVkCmdPool != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_CommandPool");
+    vkDestroyCommandPool (myDevice->Device(), myVkCmdPool, myDevice->HostAllocator());
+    myVkCmdPool = NULL;
+  }
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_CommandPool::Create (const Handle(Vulkan_Device)& theDevice)
+{
+  if (myVkCmdPool != NULL
+   && myDevice == theDevice)
+  {
+    return true;
+  }
+
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+
+  VkCommandPoolCreateInfo aVkCmdPoolInfo;
+  aVkCmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+  aVkCmdPoolInfo.pNext = NULL;
+  aVkCmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+  aVkCmdPoolInfo.queueFamilyIndex = 0;
+
+  VkResult aRes = vkCreateCommandPool (theDevice->Device(), &aVkCmdPoolInfo, theDevice->HostAllocator(), &myVkCmdPool);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create command pool", aRes);
+    return false;
+  }
+
+  if (!ResetPool())
+  {
+    Release();
+    return false;
+  }
+
+  return true;
+}
+
+// =======================================================================
+// function : ResetPool
+// purpose  :
+// =======================================================================
+bool Vulkan_CommandPool::ResetPool()
+{
+  if (myVkCmdPool == NULL)
+  {
+    return false;
+  }
+
+  VkResult aRes = vkResetCommandPool (myDevice->Device(), myVkCmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailure ("failed to reset command pool", aRes);
+    return false;
+  }
+  return true;
+}
+
+// =======================================================================
+// function : AllocateBuffers
+// purpose  :
+// =======================================================================
+Handle(Vulkan_CommandBuffer) Vulkan_CommandPool::AllocateBuffer()
+{
+  Handle(Vulkan_CommandBuffer) aBuffer = new Vulkan_CommandBuffer();
+  return aBuffer->Create (this)
+       ? aBuffer
+       : Handle(Vulkan_CommandBuffer)();
+}
diff --git a/src/Vulkan/Vulkan_CommandPool.hxx b/src/Vulkan/Vulkan_CommandPool.hxx
new file mode 100644 (file)
index 0000000..38842b5
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_CommandPool_HeaderFile
+#define _Vulkan_CommandPool_HeaderFile
+
+#include <Vulkan_Object.hxx>
+
+class Vulkan_CommandBuffer;
+
+//! This class defines an Vulkan command pool.
+class Vulkan_CommandPool : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_CommandPool, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_CommandPool();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_CommandPool();
+
+  //! Return object.
+  VkCommandPool CommandPool() const { return myVkCmdPool; }
+
+  //! Create the object, @sa vkCreateCommandPool().
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice);
+
+  //! Reset command pool, @sa vkResetCommandPool().
+  Standard_EXPORT bool ResetPool();
+
+  //! Allocate single command buffer from this pool, @sa vkAllocateCommandBuffers().
+  Handle(Vulkan_CommandBuffer) AllocateBuffer();
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releasePool(); }
+
+  //! Release the object, @sa vkDestroyCommandPool().
+  Standard_EXPORT void releasePool();
+
+protected:
+
+  VkCommandPool myVkCmdPool;
+
+};
+
+#endif // _Vulkan_CommandPool_HeaderFile
diff --git a/src/Vulkan/Vulkan_Context.cxx b/src/Vulkan/Vulkan_Context.cxx
new file mode 100644 (file)
index 0000000..215f910
--- /dev/null
@@ -0,0 +1,223 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_Context.hxx>
+
+#include <Graphic3d_Camera.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Buffer.hxx>
+#include <Vulkan_CommandBuffer.hxx>
+#include <Vulkan_CommandPool.hxx>
+#include <Vulkan_DescriptorPool.hxx>
+#include <Vulkan_DescriptorSetLayout.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_PipelineLayout.hxx>
+#include <Vulkan_Shader.hxx>
+
+#include <vulkan/vulkan.h>
+
+#include <vector>
+
+#include "Vulkan_ShaderUnlit_vs_spv.pxx"
+#include "Vulkan_ShaderUnlit_fs_spv.pxx"
+#include "Vulkan_ShaderPhong_vs_spv.pxx"
+#include "Vulkan_ShaderPhong_fs_spv.pxx"
+#include "Vulkan_ShaderFlat_vs_spv.pxx"
+#include "Vulkan_ShaderFlat_fs_spv.pxx"
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Context, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_Context
+// purpose  :
+// =======================================================================
+Vulkan_Context::Vulkan_Context (const Handle(Vulkan_Device)& theDevice)
+: myCmdBuffer (NULL)
+{
+  init (theDevice);
+}
+
+// =======================================================================
+// function : ~Vulkan_Context
+// purpose  :
+// =======================================================================
+Vulkan_Context::~Vulkan_Context()
+{
+  //
+}
+
+// =======================================================================
+// function : release
+// purpose  :
+// =======================================================================
+void Vulkan_Context::release()
+{
+  myCmdBuffer.Nullify();
+  myDescPool.Nullify();
+  myCmdPool.Nullify();
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : init
+// purpose  :
+// =======================================================================
+void Vulkan_Context::init (const Handle(Vulkan_Device)& theDevice)
+{
+  myDevice = theDevice;
+  myCmdPool = new Vulkan_CommandPool();
+  myCmdPool->Create (theDevice);
+  myDescPool = new Vulkan_DescriptorPool();
+  myDescPool->Create (theDevice);
+}
+
+// =======================================================================
+// function : SetCommandBuffer
+// purpose  :
+// =======================================================================
+void Vulkan_Context::SetCommandBuffer (const Handle(Vulkan_CommandBuffer)& theBuffer)
+{
+  myCmdBuffer = theBuffer;
+}
+
+// =======================================================================
+// function : ResetState
+// purpose  :
+// =======================================================================
+bool Vulkan_Context::ResetState (const Handle(Graphic3d_Camera)& theCamera)
+{
+  myCamera = theCamera;
+  myActivePipeline.Nullify();
+  if (!myCmdPool->ResetPool()
+   || !myDescPool->ResetPool())
+  {
+    return false;
+  }
+  return true;
+}
+
+// =======================================================================
+// function : ActivatePipeline
+// purpose  :
+// =======================================================================
+const Handle(Vulkan_Pipeline)& Vulkan_Context::ActivatePipeline (const Vulkun_PipelineCfg& theCfg)
+{
+  static Handle(Vulkan_PipelineLayout) aPipeLayout;
+  static Handle(Vulkan_DescriptorSetLayout) aDescSetLayout = new Vulkan_DescriptorSetLayout();
+  static Handle(Vulkan_Buffer) aShaderUniformBuffer;
+  if (aPipeLayout.IsNull())
+  {
+    aDescSetLayout->Create (myDevice);
+
+    aPipeLayout = new Vulkan_PipelineLayout();
+    aPipeLayout->Create (myDevice, aDescSetLayout);
+
+    aShaderUniformBuffer = new Vulkan_Buffer();
+  }
+
+  Standard_Integer anIndex = myPipelineMap.Find (theCfg);
+  if (anIndex == 0)
+  {
+    Handle(Vulkan_Shader) aShaderVert, aShaderFrag;
+    aShaderVert = new Vulkan_Shader();
+    aShaderFrag = new Vulkan_Shader();
+    if (theCfg.ShadingModel == Graphic3d_TOSM_FRAGMENT)
+    {
+      aShaderVert->Create (myDevice, Vulkan_ShaderPhong_vs_spv, sizeof(Vulkan_ShaderPhong_vs_spv));
+      aShaderFrag->Create (myDevice, Vulkan_ShaderPhong_fs_spv, sizeof(Vulkan_ShaderPhong_fs_spv));
+    }
+    else if (theCfg.ShadingModel == Graphic3d_TOSM_FACET)
+    {
+      aShaderVert->Create (myDevice, Vulkan_ShaderFlat_vs_spv, sizeof(Vulkan_ShaderFlat_vs_spv));
+      aShaderFrag->Create (myDevice, Vulkan_ShaderFlat_fs_spv, sizeof(Vulkan_ShaderFlat_fs_spv));
+    }
+    else
+    {
+      aShaderVert->Create (myDevice, Vulkan_ShaderUnlit_vs_spv, sizeof(Vulkan_ShaderUnlit_vs_spv));
+      aShaderFrag->Create (myDevice, Vulkan_ShaderUnlit_fs_spv, sizeof(Vulkan_ShaderUnlit_fs_spv));
+    }
+
+    Handle(Vulkan_Pipeline) aPipeline = new Vulkan_Pipeline();
+    aPipeline->Create (myDevice, myRenderPass, aPipeLayout, aShaderVert, aShaderFrag, Graphic3d_Vec2u (400, 400), theCfg);
+    anIndex = myPipelineMap.Add (aPipeline);
+  }
+
+  const Handle(Vulkan_Pipeline)& aPipeline = myPipelineMap.FindKey (anIndex);
+  if (myActivePipeline == aPipeline)
+  {
+    return myActivePipeline;
+  }
+
+  myActivePipeline = aPipeline;
+  struct UniformsColors
+  {
+    Graphic3d_Mat4 occWorldViewMatrix;
+    Graphic3d_Mat4 occProjectionMatrix;
+    Graphic3d_Mat4 occModelWorldMatrix;
+    Graphic3d_Vec4 uColor;
+  } aUniformsColors;
+  aUniformsColors.occProjectionMatrix = myCamera->ProjectionMatrixF();
+  aUniformsColors.occWorldViewMatrix  = myCamera->OrientationMatrixF();
+  if (theCfg.PrimType == Graphic3d_TOPA_SEGMENTS)
+  {
+    aUniformsColors.uColor.SetValues (0.0f, 0.0f, 1.0f, 1.0f);
+  }
+  else
+  {
+    aUniformsColors.uColor.SetValues (1.0f, 0.0f, 0.0f, 1.0f);
+  }
+  aShaderUniformBuffer->init (myDevice, &aUniformsColors, sizeof(aUniformsColors), Vulkan_BufferType_Uniform);
+
+  std::vector<VkDescriptorSet> aVkDescriptorSets (1, NULL);
+  {
+    std::vector<VkDescriptorSetLayout> aDescSetLayouts (1, aDescSetLayout->DescriptorSetLayout());
+    VkDescriptorSetAllocateInfo aDescSetAllocInfo = {};
+    aDescSetAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    aDescSetAllocInfo.descriptorPool = myDescPool->DescriptorPool();
+    aDescSetAllocInfo.descriptorSetCount = (uint32_t )aDescSetLayouts.size();
+    aDescSetAllocInfo.pSetLayouts = aDescSetLayouts.data();
+
+    VkResult aRes = vkAllocateDescriptorSets (myDevice->Device(), &aDescSetAllocInfo, aVkDescriptorSets.data());
+    if (aRes != VK_SUCCESS)
+    {
+      logFailure ("failed to allocate descriptor sets", aRes);
+      static const Handle(Vulkan_Pipeline) aDummy;
+      return aDummy;
+    }
+
+    VkDescriptorBufferInfo aVkDescBuffInfo = {};
+    aVkDescBuffInfo.buffer = aShaderUniformBuffer->Buffer();
+    aVkDescBuffInfo.offset = 0;
+    aVkDescBuffInfo.range  = VK_WHOLE_SIZE;
+
+    VkWriteDescriptorSet aVkWriteDescSet = {};
+    aVkWriteDescSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    aVkWriteDescSet.dstSet = aVkDescriptorSets[0];
+    aVkWriteDescSet.dstBinding = 0;
+    aVkWriteDescSet.dstArrayElement = 0;
+    aVkWriteDescSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    aVkWriteDescSet.descriptorCount = 1;
+    aVkWriteDescSet.pBufferInfo = &aVkDescBuffInfo;
+    aVkWriteDescSet.pImageInfo = NULL;
+    aVkWriteDescSet.pTexelBufferView = NULL;
+    vkUpdateDescriptorSets (myDevice->Device(), 1, &aVkWriteDescSet, 0, NULL);
+  }
+
+  myCmdBuffer->BindPipeline (aPipeline);
+  vkCmdBindDescriptorSets (myCmdBuffer->CommandBuffer(),
+                           VK_PIPELINE_BIND_POINT_GRAPHICS,
+                           aPipeline->PipelineLayout()->PipelineLayout(),
+                           0, 1, &aVkDescriptorSets[0], 0, NULL);
+  return aPipeline;
+}
diff --git a/src/Vulkan/Vulkan_Context.hxx b/src/Vulkan/Vulkan_Context.hxx
new file mode 100644 (file)
index 0000000..67757e6
--- /dev/null
@@ -0,0 +1,117 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Context_HeaderFile
+#define _Vulkan_Context_HeaderFile
+
+#include <Graphic3d_TypeOfPrimitiveArray.hxx>
+#include <NCollection_IndexedMap.hxx>
+#include <Vulkan_Object.hxx>
+#include <Vulkan_Pipeline.hxx>
+#include <TCollection_AsciiString.hxx>
+
+class Graphic3d_Camera;
+class Vulkan_CommandBuffer;
+class Vulkan_CommandPool;
+class Vulkan_DescriptorPool;
+
+//! Rendering context for Vulkan.
+class Vulkan_Context : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Context, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_Context (const Handle(Vulkan_Device)& theDevice);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_Context();
+
+  Standard_EXPORT bool ResetState (const Handle(Graphic3d_Camera)& theCamera);
+
+  //! Return camera.
+  const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
+
+  //! Set camera.
+  void SetCamera (const Handle(Graphic3d_Camera)& theCamera) { myCamera = theCamera; }
+
+  //! Return render pass.
+  const Handle(Vulkan_RenderPass)& RenderPass() const { return myRenderPass; }
+
+  //! Set render pass.
+  void SetRenderPass (const Handle(Vulkan_RenderPass)& theRenderPass) { myRenderPass = theRenderPass; }
+
+  //! Return command pool.
+  const Handle(Vulkan_CommandPool)& CommandPool() const { return myCmdPool; }
+
+  //! Return command buffer.
+  const Handle(Vulkan_CommandBuffer)& CommandBuffer() const { return myCmdBuffer; }
+
+  //! Set command buffer.
+  Standard_EXPORT void SetCommandBuffer (const Handle(Vulkan_CommandBuffer)& theBuffer);
+
+  //! Return descriptor pool.
+  const Handle(Vulkan_DescriptorPool)& DescriptorPool() const { return myDescPool; }
+
+  //! Activate pipeline.
+  Standard_EXPORT const Handle(Vulkan_Pipeline)& ActivatePipeline (const Vulkun_PipelineCfg& theCfg);
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE;
+
+  //! Initialize context.
+  Standard_EXPORT void init (const Handle(Vulkan_Device)& theDevice);
+
+  //! Map storing registered fonts.
+  class Vulkan_PipelineMap : public NCollection_IndexedMap<Handle(Vulkan_Pipeline), Vulkan_Pipeline>
+  {
+  public:
+    //! Empty constructor.
+    Vulkan_PipelineMap() {}
+
+    //! Try finding font with specified parameters or the closest one.
+    Standard_Integer Find (const Vulkun_PipelineCfg& theCfg) const
+    {
+      if (IsEmpty())
+      {
+        return 0;
+      }
+
+      for (IndexedMapNode* aNodeIter = (IndexedMapNode* )myData1[Vulkun_PipelineCfg::HashCode (theCfg, NbBuckets())];
+           aNodeIter != NULL; aNodeIter = (IndexedMapNode* )aNodeIter->Next())
+      {
+        const Handle(Vulkan_Pipeline)& aKey = aNodeIter->Key1();
+        if (aKey->Configuration().IsEqual (theCfg))
+        {
+          return aNodeIter->Index();
+        }
+      }
+      return 0;
+    }
+  };
+
+protected:
+
+  Handle(Graphic3d_Camera)      myCamera;
+  Handle(Vulkan_RenderPass)     myRenderPass;
+  Handle(Vulkan_CommandPool)    myCmdPool;
+  Handle(Vulkan_DescriptorPool) myDescPool;
+  Handle(Vulkan_CommandBuffer)  myCmdBuffer;
+  Handle(Vulkan_Pipeline)       myActivePipeline;
+  Vulkan_PipelineMap            myPipelineMap;
+
+};
+
+#endif // _Vulkan_Context_HeaderFile
diff --git a/src/Vulkan/Vulkan_DescriptorPool.cxx b/src/Vulkan/Vulkan_DescriptorPool.cxx
new file mode 100644 (file)
index 0000000..0cc0a91
--- /dev/null
@@ -0,0 +1,110 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_DescriptorPool.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_DescriptorPool, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_DescriptorPool
+// purpose  :
+// =======================================================================
+Vulkan_DescriptorPool::Vulkan_DescriptorPool()
+: myVkDescPool (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_DescriptorPool
+// purpose  :
+// =======================================================================
+Vulkan_DescriptorPool::~Vulkan_DescriptorPool()
+{
+  releasePool();
+}
+
+// =======================================================================
+// function : releaseFence
+// purpose  :
+// =======================================================================
+void Vulkan_DescriptorPool::releasePool()
+{
+  if (myVkDescPool != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_DescriptorPool");
+    vkDestroyDescriptorPool (myDevice->Device(), myVkDescPool, myDevice->HostAllocator());
+    myVkDescPool = NULL;
+  }
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_DescriptorPool::Create (const Handle(Vulkan_Device)& theDevice)
+{
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+
+  VkDescriptorPoolSize aVkPoolSize = {};
+  aVkPoolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+  aVkPoolSize.descriptorCount = 10;
+
+  VkDescriptorPoolCreateInfo aVkPoolInfo = {};
+  aVkPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+  aVkPoolInfo.poolSizeCount = 1;
+  aVkPoolInfo.pPoolSizes = &aVkPoolSize;
+  aVkPoolInfo.maxSets = 10;
+  VkResult aRes = vkCreateDescriptorPool (theDevice->Device(), &aVkPoolInfo, theDevice->HostAllocator(), &myVkDescPool);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create descriptor pool", aRes);
+    return false;
+  }
+
+  return true;
+}
+
+// =======================================================================
+// function : ResetPool
+// purpose  :
+// =======================================================================
+bool Vulkan_DescriptorPool::ResetPool()
+{
+  if (myVkDescPool == NULL)
+  {
+    return false;
+  }
+
+  VkResult aRes = vkResetDescriptorPool (myDevice->Device(), myVkDescPool, 0);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailure ("failed to reset descriptor pool", aRes);
+    return false;
+  }
+  return true;
+}
diff --git a/src/Vulkan/Vulkan_DescriptorPool.hxx b/src/Vulkan/Vulkan_DescriptorPool.hxx
new file mode 100644 (file)
index 0000000..3ae62f4
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_DescriptorPool_HeaderFile
+#define _Vulkan_DescriptorPool_HeaderFile
+
+#include <Vulkan_Object.hxx>
+
+//! This class defines an Vulkan descriptor pool.
+class Vulkan_DescriptorPool : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_DescriptorPool, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_DescriptorPool();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_DescriptorPool();
+
+  //! Return object.
+  VkDescriptorPool DescriptorPool() const { return myVkDescPool; }
+
+  //! Create the object, @sa vkCreateDescriptorPool().
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice);
+
+  //! Reset the fence, @sa vkResetDescriptorPool().
+  Standard_EXPORT bool ResetPool();
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releasePool(); }
+
+  //! Release the object, @sa vkDestroyDescriptorPool().
+  Standard_EXPORT void releasePool();
+
+protected:
+
+  VkDescriptorPool myVkDescPool;
+
+};
+
+#endif // _Vulkan_DescriptorPool_HeaderFile
diff --git a/src/Vulkan/Vulkan_DescriptorSetLayout.cxx b/src/Vulkan/Vulkan_DescriptorSetLayout.cxx
new file mode 100644 (file)
index 0000000..17f4c45
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_DescriptorSetLayout.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_DescriptorSetLayout, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_DescriptorSetLayout
+// purpose  :
+// =======================================================================
+Vulkan_DescriptorSetLayout::Vulkan_DescriptorSetLayout()
+: myVkDescSetLayout (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_DescriptorSetLayout
+// purpose  :
+// =======================================================================
+Vulkan_DescriptorSetLayout::~Vulkan_DescriptorSetLayout()
+{
+  releaseLayout();
+}
+
+// =======================================================================
+// function : releaseLayout
+// purpose  :
+// =======================================================================
+void Vulkan_DescriptorSetLayout::releaseLayout()
+{
+  if (myVkDescSetLayout != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_DescriptorSetLayout");
+    vkDestroyDescriptorSetLayout (myDevice->Device(), myVkDescSetLayout, myDevice->HostAllocator());
+    myVkDescSetLayout = NULL;
+  }
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_DescriptorSetLayout::Create (const Handle(Vulkan_Device)& theDevice)
+{
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+
+  VkDescriptorSetLayoutBinding aVkDescSetLayoutBinding = {};
+  aVkDescSetLayoutBinding.binding = 0;
+  aVkDescSetLayoutBinding.descriptorCount = 1;
+  aVkDescSetLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+  aVkDescSetLayoutBinding.pImmutableSamplers = NULL;
+  aVkDescSetLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
+  ///aVkDescSetLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+
+  VkDescriptorSetLayoutCreateInfo aVkDescLayoutInfo = {};
+  aVkDescLayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+  aVkDescLayoutInfo.bindingCount = 1;
+  aVkDescLayoutInfo.pBindings = &aVkDescSetLayoutBinding;
+  VkResult aRes = vkCreateDescriptorSetLayout (theDevice->Device(), &aVkDescLayoutInfo, theDevice->HostAllocator(), &myVkDescSetLayout);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create descriptor set layout", aRes);
+    return false;
+  }
+
+  return true;
+}
diff --git a/src/Vulkan/Vulkan_DescriptorSetLayout.hxx b/src/Vulkan/Vulkan_DescriptorSetLayout.hxx
new file mode 100644 (file)
index 0000000..b8704cf
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_DescriptorSetLayout_HeaderFile
+#define _Vulkan_DescriptorSetLayout_HeaderFile
+
+#include <Vulkan_Object.hxx>
+
+//! This class defines an Vulkan descriptor set layout.
+class Vulkan_DescriptorSetLayout : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_DescriptorSetLayout, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_DescriptorSetLayout();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_DescriptorSetLayout();
+
+  //! Return object.
+  const VkDescriptorSetLayout& DescriptorSetLayout() const { return myVkDescSetLayout; }
+
+  //! Create the object, @sa vkCreateDescriptorSetLayout().
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice);
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releaseLayout(); }
+
+  //! Release the object, @sa vkDestroyDescriptorSetLayout().
+  Standard_EXPORT void releaseLayout();
+
+protected:
+
+  VkDescriptorSetLayout myVkDescSetLayout;
+
+};
+
+#endif // _Vulkan_DescriptorSetLayout_HeaderFile
diff --git a/src/Vulkan/Vulkan_Device.cxx b/src/Vulkan/Vulkan_Device.cxx
new file mode 100644 (file)
index 0000000..defe9f2
--- /dev/null
@@ -0,0 +1,1105 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#if defined(_WIN32)
+  #include <windows.h>
+
+  #define VK_USE_PLATFORM_WIN32_KHR 1
+#endif
+
+#include <Vulkan_Device.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <NCollection_Map.hxx>
+#include <Vulkan_Caps.hxx>
+#include <Vulkan_DeviceMemoryAllocator.hxx>
+#include <Vulkan_FrameStats.hxx>
+#include <TColStd_PackedMapOfInteger.hxx>
+
+#include <vulkan/vulkan.h>
+
+#include <vector>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Device, Standard_Transient)
+
+namespace
+{
+  //! Return object type for obsolete VK_EXT_debug_report extension.
+  static TCollection_AsciiString debugVkObjectType1 (VkDebugReportObjectTypeEXT theObjectType)
+  {
+    switch (theObjectType)
+    {
+      case VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT:
+        return "UNKNOWN";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT:
+        return "VkInstance";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT:
+        return "VkPhysicalDevice";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT:
+        return "VkDevice";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT:
+        return "VkQueue";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT:
+        return "VkSemaphore";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT:
+        return "VkCommandBuffer";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT:
+        return "VkFence";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT:
+        return "Device memory";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
+        return "VkBuffer";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
+        return "VkImage";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT:
+        return "VkEvent";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT:
+        return "VkQuerypool";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT:
+        return "VkBufferView";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT:
+        return "VkImageView";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT:
+        return "VkShaderModule";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT:
+        return "VkPipelineCache";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT:
+        return "VkPipelineLayout";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT:
+        return "VkRenderPass";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT:
+        return "VkPipeline";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT:
+        return "VkDescriptorSetLayout";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT:
+        return "VkSampler";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT:
+        return "Descriptor pool";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT:
+        return "VkDescriptorSet";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT:
+        return "VkFramebuffer";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT:
+        return "VkCommandPool";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT:
+        return "VkSurface";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT:
+        return "VkSwapchainKHR";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT:
+        return "VkDebugReportCallbackEXT";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT:
+        return "VkDisplayKHR";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT:
+        return "VkDisplayModeKHR";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT:
+        return "VkObjectTableNVX";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT:
+        return "VkIndirectCommandsLayoutNVX";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT:
+        return "VkValidationCacheEXT";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT:
+        return "VkSamplerYcbcrConversion";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT:
+        return "VkDescriptorUpdateTemplate";
+      case VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT:
+        return "VkAccelerationStructureNV";
+      default:
+        return TCollection_AsciiString ("Unknown #") + (int )theObjectType;
+    }
+  }
+
+  //! Return object type.
+  static TCollection_AsciiString debugVkObjectType (VkObjectType theObjectType)
+  {
+    switch (theObjectType)
+    {
+      case VK_OBJECT_TYPE_UNKNOWN:
+        return "UNKNOWN";
+      case VK_OBJECT_TYPE_INSTANCE:
+        return "VkInstance";
+      case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
+        return "VkPhysicalDevice";
+      case VK_OBJECT_TYPE_DEVICE:
+        return "VkDevice";
+      case VK_OBJECT_TYPE_QUEUE:
+        return "VkQueue";
+      case VK_OBJECT_TYPE_SEMAPHORE:
+        return "VkSemaphore";
+      case VK_OBJECT_TYPE_COMMAND_BUFFER:
+        return "VkCommandBuffer";
+      case VK_OBJECT_TYPE_FENCE:
+        return "VkFence";
+      case VK_OBJECT_TYPE_DEVICE_MEMORY:
+        return "VkDeviceMemory";
+      case VK_OBJECT_TYPE_BUFFER:
+        return "VkBuffer";
+      case VK_OBJECT_TYPE_IMAGE:
+        return "VkImage";
+      case VK_OBJECT_TYPE_EVENT:
+        return "VkEvent";
+      case VK_OBJECT_TYPE_QUERY_POOL:
+        return "VkQueryPool";
+      case VK_OBJECT_TYPE_BUFFER_VIEW:
+        return "VkBufferView";
+      case VK_OBJECT_TYPE_IMAGE_VIEW:
+        return "VkImageView";
+      case VK_OBJECT_TYPE_SHADER_MODULE:
+        return "VkShaderModule";
+      case VK_OBJECT_TYPE_PIPELINE_CACHE:
+        return "VkPipelineCache";
+      case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
+        return "VkPipelineLayout";
+      case VK_OBJECT_TYPE_RENDER_PASS:
+        return "VkRenderPass";
+      case VK_OBJECT_TYPE_PIPELINE:
+        return "VkPipeline";
+      case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
+        return "VkDescriptorSetLayout";
+      case VK_OBJECT_TYPE_SAMPLER:
+        return "VkSampler";
+      case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
+        return "VkDescriptorPool";
+      case VK_OBJECT_TYPE_DESCRIPTOR_SET:
+        return "VkDescriptorSet";
+      case VK_OBJECT_TYPE_FRAMEBUFFER:
+        return "VkFramebuffer";
+      case VK_OBJECT_TYPE_COMMAND_POOL:
+        return "VkCommandPool";
+      case VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION:
+        return "VkSamplerYcbcrConversion";
+      case VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE:
+        return "VkDescriptorUpdateTemplate";
+      case VK_OBJECT_TYPE_SURFACE_KHR:
+        return "VkSurfaceKHR";
+      case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
+        return "VkSwapchainKHR";
+      case VK_OBJECT_TYPE_DISPLAY_KHR:
+        return "VkDisplayKHR";
+      case VK_OBJECT_TYPE_DISPLAY_MODE_KHR:
+        return "VkDisplayModeKHR";
+      case VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT:
+        return "VkDebugReportCallbackEXT";
+      case VK_OBJECT_TYPE_OBJECT_TABLE_NVX:
+        return "VkObjectTableNVX";
+      case VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX:
+        return "VkIndirectCommandsLayoutNVX";
+      case VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT:
+        return "VkDebugUtilsMessengerEXT";
+      case VK_OBJECT_TYPE_VALIDATION_CACHE_EXT:
+        return "VkValidationCacheEXT";
+      case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV:
+        return "VkAccelerationStructureNV";
+      default:
+        return TCollection_AsciiString ("Unknown #") + (int )theObjectType;
+    }
+  }
+
+  //! Format physical device type.
+  static const char* formatVkDeviceType (VkPhysicalDeviceType theType)
+  {
+    switch (theType)
+    {
+      case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: return "Integrated GPU";
+      case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:   return "Discrete GPU";
+      case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:    return "Virtual GPU";
+      case VK_PHYSICAL_DEVICE_TYPE_CPU:            return "CPU";
+      default:
+        return "UNKNOWN";
+    }
+  }
+
+  //! Return physical device priority.
+  static int fastestVkDeviceType (VkPhysicalDeviceType theType)
+  {
+    switch (theType)
+    {
+      case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: return 2;
+      case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:   return 3;
+      case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:    return 1;
+      case VK_PHYSICAL_DEVICE_TYPE_CPU:            return 0;
+      default:
+        return 0;
+    }
+  }
+
+  //! Return message type.
+  static const char* debugVkMessageType1 (VkDebugReportFlagsEXT theFlags)
+  {
+    if ((theFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0)
+    {
+      return "Error";
+    }
+    if ((theFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) != 0)
+    {
+      return "Warning";
+    }
+    if ((theFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) != 0)
+    {
+      return "Info";
+    }
+    if ((theFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) != 0)
+    {
+      return "Performance";
+    }
+    if ((theFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) != 0)
+    {
+      return "Debug";
+    }
+    return "";
+  }
+
+  //! Vulkan debug callback redirection to Message::DefaultMessenger() for VK_EXT_debug_report extension.
+  static VkBool32 VKAPI_CALL debugVkCallback1 (VkDebugReportFlagsEXT theFlags,
+                                               VkDebugReportObjectTypeEXT theObjectType,
+                                               uint64_t theObject,
+                                               size_t   theLocation,
+                                               int32_t  theMessageCode,
+                                               const char* theLayerPrefix,
+                                               const char* theMessage,
+                                               void* theUserData)
+  {
+    (void )theUserData;
+    (void )theObject;
+    (void )theLocation;
+    Message_Gravity aGrav = (theFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0
+                          ? Message_Alarm
+                          : ((theFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) != 0
+                           ? Message_Warning
+                           : Message_Info);
+    const TCollection_AsciiString aLayer = theLayerPrefix;
+    if (aLayer == "Loader Message"
+     && theObjectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT
+     && (theFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) != 0)
+    {
+      aGrav = Message_Trace;
+      return VK_FALSE;
+    }
+
+    TCollection_AsciiString aMsg;
+    aMsg += "TKVulkan.";        aMsg += aLayer;
+    aMsg += " | Type: ";        aMsg += debugVkMessageType1 (theFlags);
+    aMsg += " | ID: ";          aMsg += theMessageCode;
+    //aMsg += " | Location: ";    aMsg += (int )theLocation;
+    aMsg += " | Object: ";      aMsg += debugVkObjectType1 (theObjectType);
+    aMsg += " | Message:\n  ";
+    aMsg += theMessage;
+    Message::DefaultMessenger()->Send (aMsg, aGrav);
+    return VK_FALSE;
+  }
+
+  //! Vulkan debug callback redirection to Message::DefaultMessenger() for VK_EXT_debug_utils extension.
+  static VkBool32 VKAPI_CALL debugVkCallback2 (VkDebugUtilsMessageSeverityFlagBitsEXT theSeverity,
+                                               VkDebugUtilsMessageTypeFlagsEXT theMsgTypes,
+                                               const VkDebugUtilsMessengerCallbackDataEXT* theData,
+                                               void* theUserData)
+  {
+    (void )theUserData;
+    Message_Gravity aGrav = theSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
+                          ? Message_Alarm
+                          : (theSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
+                           ? Message_Warning
+                           : (theSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
+                            ? Message_Info
+                            : Message_Trace));
+    TCollection_AsciiString aMsgSev;
+    if ((theSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) != 0)
+    {
+      aMsgSev = "Verbose";
+    }
+    else if ((theSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) != 0)
+    {
+      aMsgSev = "Info";
+    }
+    else if ((theSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) != 0)
+    {
+      aMsgSev = "Warning";
+    }
+    else if ((theSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0)
+    {
+      aMsgSev = "Error";
+    }
+
+    TCollection_AsciiString aMsgType;
+    if ((theMsgTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) != 0)
+    {
+      aMsgType += "General";
+    }
+    if ((theMsgTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) != 0)
+    {
+      aMsgType += "Validation";
+    }
+    if ((theMsgTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) != 0)
+    {
+      aMsgType += "Performance";
+    }
+
+    const TCollection_AsciiString aMsgIdName (theData->pMessageIdName);
+    if (aGrav == Message_Info
+     && (theMsgTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) != 0
+     && aMsgIdName == "Loader Message")
+    {
+      // these messages don't look important
+      aGrav = Message_Trace;
+      return VK_FALSE;
+    }
+
+    TCollection_AsciiString aMsg;
+    aMsg += "TKVulkan.";        aMsg += aMsgType;
+    aMsg += " | Type: ";        aMsg += aMsgSev;
+    aMsg += " | ID: ";          aMsg += aMsgIdName + " [" + theData->messageIdNumber + "]";
+    aMsg += " | Message:\n  ";
+    aMsg += theData->pMessage;
+    if (theData->objectCount > 0)
+    {
+      char aValBuff[128];
+      aMsg += TCollection_AsciiString("\n  Objects ") + int(theData->objectCount) + "\n";
+      for (uint32_t anObjIter = 0; anObjIter < theData->objectCount; ++anObjIter)
+      {
+        const VkDebugUtilsObjectNameInfoEXT& anObj = theData->pObjects[anObjIter];
+        Sprintf (aValBuff, " Value %" PRIu64 "\n", anObj.objectHandle);
+        aMsg += TCollection_AsciiString("\n    Object[") + int(anObjIter) + "] - " + debugVkObjectType (anObj.objectType);
+        if (anObj.pObjectName != NULL)
+        {
+          aMsg += TCollection_AsciiString(" [") + anObj.pObjectName + "]";
+        }
+        aMsg += aValBuff;
+      }
+    }
+    if (theData->cmdBufLabelCount > 0)
+    {
+      aMsg += TCollection_AsciiString("\n  Command Buffer Labels ") + int(theData->cmdBufLabelCount) + "\n";
+      for (uint32_t aCmdIter = 0; aCmdIter < theData->cmdBufLabelCount; ++aCmdIter)
+      {
+        const VkDebugUtilsLabelEXT& aCmd = theData->pCmdBufLabels[aCmdIter];
+        aMsg += TCollection_AsciiString("\n    Label[") + int(aCmdIter) + "] - "
+              + (aCmd.pLabelName != NULL ? aCmd.pLabelName : "")
+              + " { " + aCmd.color[0] + " " + aCmd.color[1] + " " + aCmd.color[2] + " " + aCmd.color[3] + " }\n";
+      }
+    }
+
+    Message::DefaultMessenger()->Send (aMsg, aGrav);
+    return VK_FALSE;
+  }
+
+  //! Add key-value pair to the dictionary.
+  static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
+                       const TCollection_AsciiString& theKey,
+                       const TCollection_AsciiString& theValue)
+  {
+    theDict.ChangeFromIndex (theDict.Add (theKey, theValue)) = theValue;
+  }
+
+}
+
+// =======================================================================
+// function : FormatVkError
+// purpose  :
+// =======================================================================
+TCollection_AsciiString Vulkan_Device::FormatVkError (int theErr)
+{
+  switch (theErr)
+  {
+    case VK_SUCCESS:
+      return "Success";
+    case VK_NOT_READY:
+      return "Not ready";
+    case VK_TIMEOUT:
+      return "Timeout";
+    case VK_EVENT_SET:
+      return "Event set";
+    case VK_EVENT_RESET:
+      return "Event reset";
+    case VK_INCOMPLETE:
+      return "Incomplete";
+    case VK_ERROR_OUT_OF_HOST_MEMORY:
+      return "Error, out of host memory";
+    case VK_ERROR_OUT_OF_DEVICE_MEMORY:
+      return "Error, out of device memory";
+    case VK_ERROR_INITIALIZATION_FAILED:
+      return "Error, initialization failed";
+    case VK_ERROR_DEVICE_LOST:
+      return "Error, device lost";
+    case VK_ERROR_MEMORY_MAP_FAILED:
+      return "Error, memory map failed";
+    case VK_ERROR_LAYER_NOT_PRESENT:
+      return "Error, layer not present";
+    case VK_ERROR_EXTENSION_NOT_PRESENT:
+      return "Error, extension not present";
+    case VK_ERROR_FEATURE_NOT_PRESENT:
+      return "Error, feature not present";
+    case VK_ERROR_INCOMPATIBLE_DRIVER:
+      return "Error, incompatible driver";
+    case VK_ERROR_TOO_MANY_OBJECTS:
+      return "Error, too many objects";
+    case VK_ERROR_FORMAT_NOT_SUPPORTED:
+      return "Error, format not supported";
+    case VK_ERROR_FRAGMENTED_POOL:
+      return "Error, fragmented pool";
+    case VK_ERROR_OUT_OF_POOL_MEMORY:
+      return "Error, out of pool memory";
+    case VK_ERROR_INVALID_EXTERNAL_HANDLE:
+      return "Error, invalid external handle";
+    case VK_ERROR_SURFACE_LOST_KHR:
+      return "Error, surface lost";
+    case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
+      return "Error, native window in use";
+    case VK_SUBOPTIMAL_KHR:
+      return "Error, suboptimal";
+    case VK_ERROR_OUT_OF_DATE_KHR:
+      return "Error, out of date";
+    case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
+      return "Error, incompatible display";
+    case VK_ERROR_VALIDATION_FAILED_EXT:
+      return "Error, validation failed";
+    case VK_ERROR_INVALID_SHADER_NV:
+      return "Error, invalid shader";
+    case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
+      return "Error, invalid DRM format";
+    case VK_ERROR_FRAGMENTATION_EXT:
+      return "Error, fragmentation";
+    case VK_ERROR_NOT_PERMITTED_EXT:
+      return "Error, not permitted";
+    case VK_ERROR_INVALID_DEVICE_ADDRESS_EXT:
+      return "Error, invalid device address";
+    default:
+      return TCollection_AsciiString("Error #") + theErr;
+  }
+}
+
+// =======================================================================
+// function : Vulkan_Device
+// purpose  :
+// =======================================================================
+Vulkan_Device::Vulkan_Device (const TCollection_AsciiString& theAppName,
+                              const uint32_t theAppVersion,
+                              const TCollection_AsciiString& theEngineName,
+                              const uint32_t theEngineVersion)
+: myAppName (theAppName),
+  myEngineName (theEngineName),
+  myAppVersion (theAppVersion),
+  myEngineVersion (theEngineVersion),
+  myVkInstance (NULL),
+  myVkDevice (NULL),
+  myVkDeviceMemory (new VkPhysicalDeviceMemoryProperties()),
+  myFrameStats (new Vulkan_FrameStats())
+{
+  memset (myVkDeviceMemory.get(), 0, sizeof(VkPhysicalDeviceMemoryProperties));
+}
+
+// =======================================================================
+// function : ~Vulkan_Device
+// purpose  :
+// =======================================================================
+Vulkan_Device::~Vulkan_Device()
+{
+  Release();
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void Vulkan_Device::Release()
+{
+  myDevMemAllocator.Nullify();
+  memset (myVkDeviceMemory.get(), 0, sizeof(VkPhysicalDeviceMemoryProperties));
+  myVkPhysDevice = NULL;
+  if (myVkDevice != NULL)
+  {
+    vkDestroyDevice (myVkDevice, myVkHostAllocator.get());
+    myVkDevice = NULL;
+  }
+
+  if (myVkInstance != NULL)
+  {
+    vkDestroyInstance (myVkInstance, myVkHostAllocator.get());
+    myVkInstance = NULL;
+  }
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool Vulkan_Device::Init (const Handle(Vulkan_Caps)& theCaps)
+{
+  Release();
+
+  Handle(Vulkan_Caps) aCaps = theCaps;
+  if (aCaps.IsNull())
+  {
+    aCaps = new Vulkan_Caps();
+  }
+
+  NCollection_Map<TCollection_AsciiString, TCollection_AsciiString> anAllLayers;
+  {
+    uint32_t aNbLayers = 0;
+    if (vkEnumerateInstanceLayerProperties (&aNbLayers, NULL) == VK_SUCCESS
+     && aNbLayers != 0)
+    {
+      std::vector<VkLayerProperties> aLayers (aNbLayers);
+      if (vkEnumerateInstanceLayerProperties (&aNbLayers, aLayers.data()) == VK_SUCCESS)
+      {
+        for (uint32_t aLayerIter = 0; aLayerIter < aNbLayers; ++aLayerIter)
+        {
+          const VkLayerProperties& aLayerProps = aLayers[aLayerIter];
+          anAllLayers.Add (aLayerProps.layerName);
+        }
+      }
+    }
+  }
+
+  NCollection_Map<TCollection_AsciiString, TCollection_AsciiString> anAllInstExtensions;
+  {
+    uint32_t aNbExts = 0;
+    if (vkEnumerateInstanceExtensionProperties (NULL, &aNbExts, NULL) == VK_SUCCESS
+     && aNbExts != 0)
+    {
+      std::vector<VkExtensionProperties> anExts (aNbExts);
+      if (vkEnumerateInstanceExtensionProperties (NULL, &aNbExts, anExts.data()) == VK_SUCCESS)
+      {
+        for (uint32_t anExtIter = 0; anExtIter < aNbExts; ++anExtIter)
+        {
+          const VkExtensionProperties& anExtProps = anExts[anExtIter];
+          anAllInstExtensions.Add (anExtProps.extensionName);
+        }
+      }
+    }
+  }
+
+  // layers should be the same for instance and for device, while extensions may differ
+  std::vector<const char*> aLayers, anInstExtensions;
+  anInstExtensions.push_back (VK_KHR_SURFACE_EXTENSION_NAME);
+#ifdef _WIN32
+  anInstExtensions.push_back (VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
+#endif
+  if (aCaps->contextDebug)
+  {
+    if (anAllInstExtensions.Contains (VK_EXT_DEBUG_UTILS_EXTENSION_NAME))
+    {
+      anInstExtensions.push_back (VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
+    }
+    else if (anAllInstExtensions.Contains (VK_EXT_DEBUG_REPORT_EXTENSION_NAME))
+    {
+      anInstExtensions.push_back (VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
+    }
+
+    // VK_LAYER_LUNARG_standard_validation is a meta layer enabling several standard validation layers (LunarG SDK):
+    // - VK_LAYER_GOOGLE_threading, VK_LAYER_GOOGLE_unique_objects,
+    //   VK_LAYER_LUNARG_parameter_validation, VK_LAYER_LUNARG_core_validation,
+    //   VK_LAYER_LUNARG_device_limits, VK_LAYER_LUNARG_image,
+    //   VK_LAYER_LUNARG_object_tracker, VK_LAYER_LUNARG_swapchain
+    if (anAllLayers.Contains ("VK_LAYER_LUNARG_standard_validation"))
+    {
+      aLayers.push_back ("VK_LAYER_LUNARG_standard_validation");
+    }
+    //aLayers.push_back ("VK_LAYER_GOOGLE_threading"); // validate usage from multiple threads
+    //aLayers.push_back ("VK_LAYER_GOOGLE_unique_objects");
+    //aLayers.push_back ("VK_LAYER_LUNARG_parameter_validation"); // validate API parameter values
+    //aLayers.push_back ("VK_LAYER_LUNARG_core_validation");
+    //aLayers.push_back ("VK_LAYER_LUNARG_device_limits"); // detects missing device limits checks
+    //aLayers.push_back ("VK_LAYER_LUNARG_image"); // validate texture/render formats
+    //aLayers.push_back ("VK_LAYER_LUNARG_object_tracker"); // detect usage of invalid objects
+    //aLayers.push_back ("VK_LAYER_LUNARG_swapchain"); // validate usage of swapchain extensions
+
+    // trace API calls
+    //if (anAllLayers.Contains ("VK_LAYER_LUNARG_api_dump"))
+    //{
+    //  aLayers.push_back ("VK_LAYER_LUNARG_api_dump");
+    //}
+    // dump frames to image files
+    //if (anAllLayers.Contains ("VK_LAYER_LUNARG_screenshot"))
+    //{
+    //  aLayers.push_back ("VK_LAYER_LUNARG_screenshot");
+    //}
+  }
+  
+  //aLayers.push_back ("VK_LAYER_NV_optimus");
+  //aLayers.push_back ("VK_LAYER_VALVE_steam_overlay");
+
+  VkApplicationInfo anAppInfo;
+  anAppInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+  anAppInfo.pNext = NULL;
+  anAppInfo.pApplicationName = myAppName.ToCString();
+  anAppInfo.applicationVersion = myAppVersion;
+  anAppInfo.pEngineName = myEngineName.ToCString();
+  anAppInfo.engineVersion = myEngineVersion;
+  anAppInfo.apiVersion = VK_MAKE_VERSION(1, 1, 0);
+
+  VkInstanceCreateInfo anInstInfo;
+  anInstInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+  anInstInfo.pNext = NULL;
+  anInstInfo.flags = 0;
+  anInstInfo.pApplicationInfo = &anAppInfo;
+  anInstInfo.enabledLayerCount   = (uint32_t )aLayers.size();
+  anInstInfo.ppEnabledLayerNames = aLayers.data();
+  anInstInfo.enabledExtensionCount   = (uint32_t )anInstExtensions.size();
+  anInstInfo.ppEnabledExtensionNames = anInstExtensions.data();
+
+  VkResult aRes = vkCreateInstance (&anInstInfo, myVkHostAllocator.get(), &myVkInstance);
+  if (aRes != VK_SUCCESS)
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Device, unable creating Vulkan instance: ") + FormatVkError (aRes), Message_Fail);
+    Release();
+    return false;
+  }
+
+  if (aCaps->contextDebug)
+  {
+    if (anAllInstExtensions.Contains (VK_EXT_DEBUG_UTILS_EXTENSION_NAME))
+    {
+      if (PFN_vkCreateDebugUtilsMessengerEXT aVkCreateDebug2 = (PFN_vkCreateDebugUtilsMessengerEXT )vkGetInstanceProcAddr (myVkInstance, "vkCreateDebugUtilsMessengerEXT"))
+      {
+        VkDebugUtilsMessengerCreateInfoEXT aCallbackInfo = {};
+        aCallbackInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
+        aCallbackInfo.flags = 0;
+        aCallbackInfo.pNext = NULL;
+        aCallbackInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
+                                      | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
+                                      | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
+                                      | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
+        aCallbackInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
+                                  | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
+                                  | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+        aCallbackInfo.pfnUserCallback = debugVkCallback2;
+        aCallbackInfo.pUserData       = NULL;
+
+        VkDebugUtilsMessengerEXT aDebReportObj = NULL;
+        aRes = aVkCreateDebug2 (myVkInstance, &aCallbackInfo, myVkHostAllocator.get(), &aDebReportObj);
+        if (aRes != VK_SUCCESS)
+        {
+          Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Device, unable registering debug report callback: ") + FormatVkError (aRes), Message_Warning);
+        }
+      }
+    }
+    else if (anAllInstExtensions.Contains (VK_EXT_DEBUG_REPORT_EXTENSION_NAME))
+    {
+      if (PFN_vkCreateDebugReportCallbackEXT aVkCreateDebug1 = (PFN_vkCreateDebugReportCallbackEXT )vkGetInstanceProcAddr (myVkInstance, "vkCreateDebugReportCallbackEXT"))
+      {
+        VkDebugReportCallbackCreateInfoEXT aCallbackInfo = {};
+        aCallbackInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
+        aCallbackInfo.pNext = NULL;
+        aCallbackInfo.flags = VK_DEBUG_REPORT_INFORMATION_BIT_EXT
+                            | VK_DEBUG_REPORT_WARNING_BIT_EXT
+                            | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT
+                            | VK_DEBUG_REPORT_ERROR_BIT_EXT
+                            | VK_DEBUG_REPORT_DEBUG_BIT_EXT;
+        aCallbackInfo.pfnCallback = debugVkCallback1;
+        aCallbackInfo.pUserData   = NULL;
+
+        VkDebugReportCallbackEXT aDebReportObj = NULL;
+        aRes = aVkCreateDebug1 (myVkInstance, &aCallbackInfo, myVkHostAllocator.get(), &aDebReportObj);
+        if (aRes != VK_SUCCESS)
+        {
+          Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Device, unable registering debug report callback: ") + FormatVkError (aRes), Message_Warning);
+        }
+      }
+    }
+  }
+
+  {
+    uint32_t aNbDevices = 0;
+    aRes = vkEnumeratePhysicalDevices (myVkInstance, &aNbDevices, NULL);
+    if (aRes != VK_SUCCESS
+     || aNbDevices == 0)
+    {
+      Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Device, unable to list physical devices: ") + FormatVkError (aRes), Message_Warning);
+      Release();
+      return false;
+    }
+
+    std::vector<VkPhysicalDevice> aDevices (aNbDevices);
+    aRes = vkEnumeratePhysicalDevices (myVkInstance, &aNbDevices, aDevices.data());
+    if (aRes != VK_SUCCESS)
+    {
+      Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Device, unable to list physical devices: ") + FormatVkError (aRes), Message_Warning);
+      return false;
+    }
+    myVkPhysDevice = aDevices[0];
+    int aSelPriority = aCaps->contextNoAccel ? IntegerLast() : -IntegerLast();
+    TCollection_AsciiString aDevNameToFind = aCaps->contextDevice;
+    aDevNameToFind.LowerCase();
+    if (aDevNameToFind.IsIntegerValue()
+     && aDevNameToFind.IntegerValue() >= 0
+     && aDevNameToFind.IntegerValue() < (int )aNbDevices)
+    {
+      myVkPhysDevice = aDevices[aDevNameToFind.IntegerValue()];
+    }
+    else
+    {
+      uint32_t aVendorToFind = 0;
+      if (aDevNameToFind == "amd")
+      {
+        aVendorToFind = VendorId_AMD;
+        aDevNameToFind.Clear();
+      }
+      else if (aDevNameToFind == "nvidia")
+      {
+        aVendorToFind = VendorId_NVIDIA;
+        aDevNameToFind.Clear();
+      }
+      else if (aDevNameToFind == "intel")
+      {
+        aVendorToFind = VendorId_INTEL;
+        aDevNameToFind.Clear();
+      }
+
+      for (uint32_t aDevIter = 0; aDevIter < aNbDevices; ++aDevIter)
+      {
+        const VkPhysicalDevice& aPhysDev = aDevices[aDevIter];
+
+        VkPhysicalDeviceProperties aDevProps;
+        memset (&aDevProps, 0, sizeof(aDevProps));
+        vkGetPhysicalDeviceProperties (aPhysDev, &aDevProps);
+        if (!aDevNameToFind.IsEmpty())
+        {
+          TCollection_AsciiString aName (aDevProps.deviceName);
+          aName.LowerCase();
+          if (aName.Search (aDevNameToFind) != -1)
+          {
+            myVkPhysDevice = aDevices[aDevIter];
+            break;
+          }
+        }
+        else if (aVendorToFind != 0
+              && aDevProps.vendorID == aVendorToFind)
+        {
+          myVkPhysDevice = aDevices[aDevIter];
+          break;
+        }
+
+        const int aPriority = fastestVkDeviceType (aDevProps.deviceType);
+        if (aCaps->contextNoAccel)
+        {
+          if (aPriority < aSelPriority)
+          {
+            aSelPriority   = aPriority;
+            myVkPhysDevice = aDevices[aDevIter];
+          }
+        }
+        else
+        {
+          if (aPriority > aSelPriority)
+          {
+            aSelPriority   = aPriority;
+            myVkPhysDevice = aDevices[aDevIter];
+          }
+        }
+      }
+    }
+  }
+
+  NCollection_Map<TCollection_AsciiString, TCollection_AsciiString> anAllDevExtensions;
+  {
+    uint32_t aNbExts = 0;
+    if (vkEnumerateDeviceExtensionProperties (myVkPhysDevice, NULL, &aNbExts, NULL) == VK_SUCCESS
+     && aNbExts != 0)
+    {
+      std::vector<VkExtensionProperties> anExts (aNbExts);
+      if (vkEnumerateDeviceExtensionProperties (myVkPhysDevice, NULL, &aNbExts, anExts.data()) == VK_SUCCESS)
+      {
+        for (uint32_t anExtIter = 0; anExtIter < aNbExts; ++anExtIter)
+        {
+          const VkExtensionProperties& anExtProps = anExts[anExtIter];
+          anAllDevExtensions.Add (anExtProps.extensionName);
+        }
+      }
+    }
+  }
+
+  std::vector<const char*> aDevExtensions;
+  aDevExtensions.push_back (VK_KHR_SWAPCHAIN_EXTENSION_NAME);
+  const bool toUseDedicatedDevMem = anAllDevExtensions.Contains (VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME)
+                                 && anAllDevExtensions.Contains (VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
+  if (anAllDevExtensions.Contains (VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME))
+  {
+    aDevExtensions.push_back (VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
+  }
+  if (anAllDevExtensions.Contains (VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME))
+  {
+    aDevExtensions.push_back (VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
+  }
+
+  std::vector<VkQueueFamilyProperties> aPhysDevQueueFamilyProps;
+  {
+    uint32_t aNbProps = 0;
+    vkGetPhysicalDeviceQueueFamilyProperties (myVkPhysDevice, &aNbProps, NULL);
+    if (aNbProps != 0)
+    {
+      aPhysDevQueueFamilyProps.resize (aNbProps);
+      vkGetPhysicalDeviceQueueFamilyProperties (myVkPhysDevice, &aNbProps, aPhysDevQueueFamilyProps.data());
+    }
+  }
+
+  {
+    std::vector<VkDeviceQueueCreateInfo> aDevQueueInfos (1);
+    std::vector< std::vector<float> > aDevQueuesPriorities (aDevQueueInfos.size(), std::vector<float> (1, 0.0f));
+    for (uint32_t aQueueIter = 0; aQueueIter < (uint32_t )aDevQueueInfos.size(); ++aQueueIter)
+    {
+      std::vector<float>& aDevQueuePriorities = aDevQueuesPriorities[aQueueIter];
+      VkDeviceQueueCreateInfo& aDevQueueInfo = aDevQueueInfos[aQueueIter];
+      aDevQueueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+      aDevQueueInfo.pNext = NULL;
+      aDevQueueInfo.flags = 0;
+      aDevQueueInfo.queueFamilyIndex = aQueueIter;
+      aDevQueueInfo.queueCount       = (uint32_t )aDevQueuePriorities.size();
+      aDevQueueInfo.pQueuePriorities = aDevQueuePriorities.data();
+    }
+
+    VkPhysicalDeviceFeatures aPhysDevFeatures;
+    memset (&aPhysDevFeatures, 0, sizeof(aPhysDevFeatures));
+
+    VkDeviceCreateInfo aDevInfo;
+    aDevInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+    aDevInfo.pNext = NULL;
+    aDevInfo.flags = 0;
+    aDevInfo.queueCreateInfoCount = (uint32_t )aDevQueueInfos.size();
+    aDevInfo.pQueueCreateInfos    = aDevQueueInfos.data();
+    aDevInfo.enabledLayerCount    = (uint32_t )aLayers.size();
+    aDevInfo.ppEnabledLayerNames  = aLayers.data();
+    aDevInfo.enabledExtensionCount   = (uint32_t )aDevExtensions.size();
+    aDevInfo.ppEnabledExtensionNames = aDevExtensions.data();
+    aDevInfo.pEnabledFeatures = &aPhysDevFeatures;
+    aRes = vkCreateDevice (myVkPhysDevice, &aDevInfo, myVkHostAllocator.get(), &myVkDevice);
+    if (aRes != VK_SUCCESS)
+    {
+      Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Device, unable to create device: ") + FormatVkError (aRes), Message_Warning);
+      Release();
+      return false;
+    }
+  }
+
+  vkGetPhysicalDeviceMemoryProperties (myVkPhysDevice, myVkDeviceMemory.get());
+
+  myDevMemAllocator = new Vulkan_DeviceMemoryAllocator();
+  if (!myDevMemAllocator->Create (this, toUseDedicatedDevMem))
+  {
+    Release();
+    return false;
+  }
+
+  return true;
+}
+
+// =======================================================================
+// function : allocateDeviceMemory
+// purpose  :
+// =======================================================================
+VkDeviceMemory Vulkan_Device::allocateDeviceMemory (const VkMemoryRequirements& theReqs)
+{
+  if (myVkInstance == NULL)
+  {
+    return NULL;
+  }
+
+  VkMemoryAllocateInfo aVkAllocInfo = {};
+  aVkAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+  aVkAllocInfo.pNext = NULL;
+  aVkAllocInfo.allocationSize = theReqs.size;
+  aVkAllocInfo.memoryTypeIndex = uint32_t(-1);
+
+  // memoryTypeBits is a bitfield where if bit i'th is set, it means that the VkMemoryType i of the VkPhysicalDeviceMemoryProperties
+  // structure satisfies the memory requirements
+  for (uint32_t aTypeIter = 0; aTypeIter < myVkDeviceMemory->memoryTypeCount; ++aTypeIter)
+  {
+    const uint32_t aBit = (uint32_t(1) << aTypeIter);
+    if ((theReqs.memoryTypeBits & aBit) != 0)
+    {
+      if ((myVkDeviceMemory->memoryTypes[aTypeIter].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
+      {
+        aVkAllocInfo.memoryTypeIndex = aTypeIter;
+        break;
+      }
+    }
+  }
+  if (aVkAllocInfo.memoryTypeIndex == uint32_t(-1))
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Device, failed to get correct memory type"), Message_Fail);
+    return NULL;
+  }
+
+  VkDeviceMemory aVkDevMem = NULL;
+  VkResult aRes = vkAllocateMemory (myVkDevice, &aVkAllocInfo, myVkHostAllocator.get(), &aVkDevMem);
+  if (aRes != VK_SUCCESS)
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Device, failed to allocate device memory [")
+                                     + int(theReqs.size) + "]:" + FormatVkError (aRes), Message_Fail);
+    return NULL;
+  }
+  return aVkDevMem;
+}
+
+// =======================================================================
+// function : DiagnosticInformation
+// purpose  :
+// =======================================================================
+void Vulkan_Device::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
+                                           Graphic3d_DiagnosticInfo theFlags) const
+{
+  if (myVkInstance == NULL)
+  {
+    return;
+  }
+
+  uint32_t aNbDevices = 0;
+  if (vkEnumeratePhysicalDevices (myVkInstance, &aNbDevices, NULL) == VK_SUCCESS
+   && aNbDevices > 1)
+  {
+    std::vector<VkPhysicalDevice> aDevices (aNbDevices);
+    if (vkEnumeratePhysicalDevices (myVkInstance, &aNbDevices, aDevices.data()) == VK_SUCCESS)
+    {
+      TCollection_AsciiString aDevListStr;
+      for (uint32_t aDevIter = 0; aDevIter < aNbDevices; ++aDevIter)
+      {
+        const VkPhysicalDevice& aPhysDev = aDevices[aDevIter];
+        VkPhysicalDeviceProperties aDevProps;
+        memset (&aDevProps, 0, sizeof(aDevProps));
+        vkGetPhysicalDeviceProperties (aPhysDev, &aDevProps);
+        aDevListStr += aDevProps.deviceName;
+        aDevListStr += " ";
+      }
+      addInfo (theDict, "VKDeviceList", aDevListStr);
+    }
+  }
+
+  if (myVkPhysDevice != NULL
+   && (theFlags & Graphic3d_DiagnosticInfo_Device) != 0)
+  {
+    VkPhysicalDeviceProperties aDevProps;
+    memset (&aDevProps, 0, sizeof(aDevProps));
+    vkGetPhysicalDeviceProperties (myVkPhysDevice, &aDevProps);
+    addInfo (theDict, "VKDevice",     aDevProps.deviceName);
+    addInfo (theDict, "VKDeviceType", formatVkDeviceType (aDevProps.deviceType));
+    TCollection_AsciiString anApiVer = TCollection_AsciiString() + (int)VK_VERSION_MAJOR(aDevProps.apiVersion)
+                                                           + "." + (int)VK_VERSION_MINOR(aDevProps.apiVersion)
+                                                           + "." + (int)VK_VERSION_PATCH(aDevProps.apiVersion);
+    TCollection_AsciiString aVendor (int(aDevProps.vendorID));
+    switch ((int )aDevProps.vendorID)
+    {
+      case VendorId_AMD:    aVendor = "AMD";    break;
+      case VendorId_NVIDIA: aVendor = "NVIDIA"; break;
+      case VendorId_INTEL:  aVendor = "INTEL";  break;
+    }
+    addInfo (theDict, "VKDeviceVendor", aVendor);
+    addInfo (theDict, "VKDeviceApiVersion", anApiVer);
+  }
+
+  if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
+  {
+    TCollection_AsciiString aLayerStr;
+    uint32_t aNbLayers = 0;
+    if ((theFlags & Graphic3d_DiagnosticInfo_NativePlatform) != 0
+     && vkEnumerateInstanceLayerProperties (&aNbLayers, NULL) == VK_SUCCESS
+     && aNbLayers != 0)
+    {
+      std::vector<VkLayerProperties> aLayers (aNbLayers);
+      if (vkEnumerateInstanceLayerProperties (&aNbLayers, aLayers.data()) == VK_SUCCESS)
+      {
+        for (uint32_t aLayerIter = 0; aLayerIter < aNbLayers; ++aLayerIter)
+        {
+          const VkLayerProperties& aLayerProps = aLayers[aLayerIter];
+          aLayerStr += aLayerProps.layerName;
+          aLayerStr += " ";
+        }
+        addInfo (theDict, "VKLayers", aLayerStr);
+      }
+    }
+
+    TCollection_AsciiString anInstExtsStr;
+    uint32_t aNbExts = 0;
+    if ((theFlags & Graphic3d_DiagnosticInfo_NativePlatform) != 0
+     && vkEnumerateInstanceExtensionProperties (NULL, &aNbExts, NULL) == VK_SUCCESS
+     && aNbExts != 0)
+    {
+      std::vector<VkExtensionProperties> anExts (aNbExts);
+      if (vkEnumerateInstanceExtensionProperties (NULL, &aNbExts, anExts.data()) == VK_SUCCESS)
+      {
+        for (uint32_t anExtIter = 0; anExtIter < aNbExts; ++anExtIter)
+        {
+          const VkExtensionProperties& anExtProps = anExts[anExtIter];
+          anInstExtsStr += anExtProps.extensionName;
+          anInstExtsStr += " ";
+        }
+        addInfo (theDict, "VKExtensions", anInstExtsStr);
+      }
+    }
+
+    TCollection_AsciiString aDevExtsStr;
+    if (myVkPhysDevice != NULL
+     && (theFlags & Graphic3d_DiagnosticInfo_Device) != 0
+     && vkEnumerateDeviceExtensionProperties (myVkPhysDevice, NULL, &aNbExts, NULL) == VK_SUCCESS
+     && aNbExts != 0)
+    {
+      std::vector<VkExtensionProperties> anExts (aNbExts);
+      if (vkEnumerateDeviceExtensionProperties (myVkPhysDevice, NULL, &aNbExts, anExts.data()) == VK_SUCCESS)
+      {
+        for (uint32_t anExtIter = 0; anExtIter < aNbExts; ++anExtIter)
+        {
+          const VkExtensionProperties& anExtProps = anExts[anExtIter];
+          aDevExtsStr += anExtProps.extensionName;
+          aDevExtsStr += " ";
+        }
+        addInfo (theDict, "VKDeviceExtensions", aDevExtsStr);
+      }
+    }
+  }
+
+  if (myVkPhysDevice != NULL
+   && (theFlags & Graphic3d_DiagnosticInfo_Limits) != 0)
+  {
+    VkPhysicalDeviceProperties aProps;
+    memset (&aProps, 0, sizeof(aProps));
+    vkGetPhysicalDeviceProperties (myVkPhysDevice, &aProps);
+    const VkPhysicalDeviceLimits& aLimits = aProps.limits;
+    addInfo (theDict, "Max texture size", TCollection_AsciiString((int )aLimits.maxImageDimension2D));
+    addInfo (theDict, "Max FBO dump size", TCollection_AsciiString() + int(aLimits.maxFramebufferWidth) + "x" + int(aLimits.maxFramebufferHeight));
+  }
+
+  if (myVkPhysDevice != NULL
+   && (theFlags & Graphic3d_DiagnosticInfo_Memory) != 0)
+  {
+    uint64_t aDedicated = 0;
+    int aNbDedicatedHeaps = 0;
+    TCollection_AsciiString aDedicatedHeaps;
+    TColStd_PackedMapOfInteger aDedicatedHeapsMap;
+    for (uint32_t aTypeIter = 0; aTypeIter < myVkDeviceMemory->memoryTypeCount; ++aTypeIter)
+    {
+      const VkMemoryType& aMemInfo = myVkDeviceMemory->memoryTypes[aTypeIter];
+      if ((aMemInfo.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) == 0)
+      {
+        continue;
+      }
+
+      if (aDedicatedHeapsMap.Add (aMemInfo.heapIndex))
+      {
+        const VkMemoryHeap& aHeap = myVkDeviceMemory->memoryHeaps[aMemInfo.heapIndex];
+        aDedicated += aHeap.size;
+        if (!aDedicatedHeaps.IsEmpty())
+        {
+          aDedicatedHeaps += ", ";
+        }
+        aDedicatedHeaps += TCollection_AsciiString(int(aHeap.size / (1024 * 1024))) + " MiB";
+        ++aNbDedicatedHeaps;
+      }
+    }
+    if (aDedicated != 0)
+    {
+      addInfo (theDict, "GPU memory", TCollection_AsciiString() + int(aDedicated / (1024 * 1024)) + " MiB");
+      if (aNbDedicatedHeaps > 1)
+      {
+        addInfo (theDict, "GPU heaps", aDedicatedHeaps);
+      }
+    }
+  }
+}
diff --git a/src/Vulkan/Vulkan_Device.hxx b/src/Vulkan/Vulkan_Device.hxx
new file mode 100644 (file)
index 0000000..7e8e95c
--- /dev/null
@@ -0,0 +1,123 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Device_HeaderFile
+#define _Vulkan_Device_HeaderFile
+
+#include <Graphic3d_DiagnosticInfo.hxx>
+#include <Vulkan_ForwardDecl.hxx>
+#include <Standard_Type.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TColStd_IndexedDataMapOfStringString.hxx>
+
+#include <memory>
+
+class Vulkan_Caps;
+class Vulkan_FrameStats;
+class Vulkan_DeviceMemoryAllocator;
+
+//! This class defines an Vulkan graphic driver
+class Vulkan_Device : public Standard_Transient
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Device, Standard_Transient)
+public:
+
+  //! Format VkResult enumeration.
+  Standard_EXPORT static TCollection_AsciiString FormatVkError (int theErr);
+
+  //! Enumeration of known vendor ids.
+  enum VendorId
+  {
+    VendorId_AMD    = 0x1002,
+    VendorId_NVIDIA = 0x10DE,
+    VendorId_INTEL  = 0x8086,
+  };
+
+public:
+
+  //! Constructor.
+  //! @param theAppName    application    name to be passed to driver
+  //! @param theAppVersion application version to be passed to driver, see VK_MAKE_VERSION() macros
+  //! @param theEngineName      engine    name to be passed to driver
+  //! @param theEngineVersion   engine version to be passed to driver, see VK_MAKE_VERSION() macros
+  Standard_EXPORT Vulkan_Device (const TCollection_AsciiString& theAppName,
+                                 const uint32_t theAppVersion,
+                                 const TCollection_AsciiString& theEngineName,
+                                 const uint32_t theEngineVersion);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_Device();
+
+  //! Release object.
+  Standard_EXPORT void Release();
+
+  //! Perform initialization.
+  Standard_EXPORT bool Init (const Handle(Vulkan_Caps)& theCaps);
+
+  //! Return vulkan instance.
+  VkInstance Instance() const { return myVkInstance; }
+  
+  //! Return device.
+  VkDevice Device() const { return myVkDevice; }
+
+  //! Return physical device.
+  VkPhysicalDevice PhysicalDevice() const { return myVkPhysDevice; }
+
+  //! Return custom allocator.
+  const VkAllocationCallbacks* HostAllocator() const { return myVkHostAllocator.get(); }
+
+  //! Return application identifier specified at construction time.
+  const TCollection_AsciiString& ApplicationName() const { return myAppName; }
+
+  //! Return engine identifier specified at construction time.
+  const TCollection_AsciiString& EngineName() const { return myEngineName; }
+  
+  //! Return application version specified at construction time.
+  uint32_t ApplicationVersion() const { return myAppVersion; }
+
+  //! Return engine version specified at construction time.
+  uint32_t EngineVersion() const { return myEngineVersion; }
+
+  //! Return frame stats.
+  const Handle(Vulkan_FrameStats)& FrameStats() const { return myFrameStats; }
+
+  //! Return device memory allocator.
+  const Handle(Vulkan_DeviceMemoryAllocator)& DeviceMemoryAllocator() const { return myDevMemAllocator; }
+
+  //! Allocate device memory.
+  Standard_EXPORT VkDeviceMemory allocateDeviceMemory (const VkMemoryRequirements& theReqs);
+
+  //! Fill map with diagnostics information.
+  Standard_EXPORT void DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
+                                              Graphic3d_DiagnosticInfo theFlags) const;
+
+protected:
+
+  TCollection_AsciiString   myAppName;         //!< application identifier to be passed to driver
+  TCollection_AsciiString   myEngineName;      //!<      engine identifier to be passed to driver
+  uint32_t                  myAppVersion;      //!< application    version to be passed to driver
+  uint32_t                  myEngineVersion;   //!<      engine    version to be passed to driver
+
+  VkInstance                myVkInstance;      //!< vulkan instance
+  VkPhysicalDevice          myVkPhysDevice;    //!< physical device
+  VkDevice                  myVkDevice;        //!< device
+  std::shared_ptr<VkAllocationCallbacks>
+                            myVkHostAllocator; //!< optional host memory allocator
+  std::shared_ptr<VkPhysicalDeviceMemoryProperties>
+                            myVkDeviceMemory;
+  Handle(Vulkan_FrameStats) myFrameStats;
+  Handle(Vulkan_DeviceMemoryAllocator) myDevMemAllocator;
+
+};
+
+#endif // _Vulkan_Device_HeaderFile
diff --git a/src/Vulkan/Vulkan_DeviceMemory.cxx b/src/Vulkan/Vulkan_DeviceMemory.cxx
new file mode 100644 (file)
index 0000000..dbdd4c4
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_DeviceMemory.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_DeviceMemoryAllocator.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_DeviceMemory, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_DeviceMemory
+// purpose  :
+// =======================================================================
+Vulkan_DeviceMemory::Vulkan_DeviceMemory (const Handle(Vulkan_DeviceMemoryAllocator)& theAllocator,
+                                          void* theOpaque)
+: myAllocator (theAllocator),
+  myOpaque (theOpaque)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_DeviceMemory
+// purpose  :
+// =======================================================================
+Vulkan_DeviceMemory::~Vulkan_DeviceMemory()
+{
+  releaseRegion();
+}
+
+// =======================================================================
+// function : DeviceMemoryInfo
+// purpose  :
+// =======================================================================
+Vulkan_DeviceMemoryInfo Vulkan_DeviceMemory::DeviceMemoryInfo() const
+{
+  return myOpaque != NULL ? myAllocator->memoryRegionInfo (*this) : Vulkan_DeviceMemoryInfo();
+}
+
+// =======================================================================
+// function : releaseRegion
+// purpose  :
+// =======================================================================
+void Vulkan_DeviceMemory::releaseRegion()
+{
+  if (myOpaque != NULL)
+  {
+    myAllocator->memoryRegionFree (*this);
+  }
+  myAllocator.Nullify();
+}
diff --git a/src/Vulkan/Vulkan_DeviceMemory.hxx b/src/Vulkan/Vulkan_DeviceMemory.hxx
new file mode 100644 (file)
index 0000000..14a7c82
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_DeviceMemory_HeaderFile
+#define _Vulkan_DeviceMemory_HeaderFile
+
+#include <Vulkan_Object.hxx>
+
+class Vulkan_DeviceMemoryAllocator;
+
+//! Device memory region information.
+struct Vulkan_DeviceMemoryInfo
+{
+  VkDeviceMemory DeviceMemory;
+  VkDeviceSize   Offset;
+  VkDeviceSize   Size;
+
+  Vulkan_DeviceMemoryInfo() : DeviceMemory (NULL), Offset (0), Size (0) {}
+};
+
+//! This class defines an device memory block.
+class Vulkan_DeviceMemory : public Standard_Transient
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_DeviceMemory, Standard_Transient)
+  friend class Vulkan_DeviceMemoryAllocator;
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_DeviceMemory();
+
+  //! Return memory region.
+  Standard_EXPORT Vulkan_DeviceMemoryInfo DeviceMemoryInfo() const;
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_DeviceMemory (const Handle(Vulkan_DeviceMemoryAllocator)& theAllocator,
+                                       void* theOpaque);
+
+  //! Release the object.
+  void release() { releaseRegion(); }
+
+  //! Release the object.
+  Standard_EXPORT void releaseRegion();
+
+protected:
+
+  Handle(Vulkan_DeviceMemoryAllocator) myAllocator;
+  void* myOpaque;
+
+};
+
+#endif // _Vulkan_DeviceMemory_HeaderFile
diff --git a/src/Vulkan/Vulkan_DeviceMemoryAllocator.cxx b/src/Vulkan/Vulkan_DeviceMemoryAllocator.cxx
new file mode 100644 (file)
index 0000000..c975279
--- /dev/null
@@ -0,0 +1,199 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_DeviceMemoryAllocator.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_DeviceMemory.hxx>
+
+#include <vulkan/vulkan.h>
+
+#ifdef max
+  #undef min
+  #undef max
+#endif
+#define VMA_IMPLEMENTATION
+#include <Standard_WarningsDisable.hxx>
+#include <vk_mem_alloc.h>
+#include <Standard_WarningsRestore.hxx>
+
+namespace
+{
+  static VmaMemoryUsage memUsageOcctToVma (Vulkan_DeviceMemoryUsage theUsage)
+  {
+    switch (theUsage)
+    {
+      case Vulkan_DeviceMemoryUsage_UNKNOWN:  return VMA_MEMORY_USAGE_UNKNOWN;
+      case Vulkan_DeviceMemoryUsage_GpuOnly:  return VMA_MEMORY_USAGE_GPU_ONLY;
+      case Vulkan_DeviceMemoryUsage_CpuOnly:  return VMA_MEMORY_USAGE_CPU_ONLY;
+      case Vulkan_DeviceMemoryUsage_CpuToGpu: return VMA_MEMORY_USAGE_CPU_TO_GPU;
+      case Vulkan_DeviceMemoryUsage_GpuToCpu: return VMA_MEMORY_USAGE_GPU_TO_CPU;
+    }
+    return VMA_MEMORY_USAGE_UNKNOWN;
+  }
+}
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_DeviceMemoryAllocator, Standard_Transient)
+
+// =======================================================================
+// function : Vulkan_DeviceMemory
+// purpose  :
+// =======================================================================
+Vulkan_DeviceMemoryAllocator::Vulkan_DeviceMemoryAllocator()
+: myVmaAllocator (NULL),
+  myDevice (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_DeviceMemoryAllocator
+// purpose  :
+// =======================================================================
+Vulkan_DeviceMemoryAllocator::~Vulkan_DeviceMemoryAllocator()
+{
+  releaseAllocator();
+}
+
+// =======================================================================
+// function : releaseAllocator
+// purpose  :
+// =======================================================================
+void Vulkan_DeviceMemoryAllocator::releaseAllocator()
+{
+  if (myVmaAllocator != NULL)
+  {
+    vmaDestroyAllocator (myVmaAllocator);
+    myVmaAllocator = NULL;
+  }
+  myDevice = NULL;
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_DeviceMemoryAllocator::Create (const Handle(Vulkan_Device)& theDevice,
+                                           bool toUseDedicatedAllocs)
+{
+  release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice.get();
+
+  VmaAllocatorCreateInfo aVmaAllocInfo = {};
+  aVmaAllocInfo.physicalDevice = theDevice->PhysicalDevice();
+  aVmaAllocInfo.device = theDevice->Device();
+  aVmaAllocInfo.flags  = 0;
+  if (toUseDedicatedAllocs)
+  {
+    // will be used by vmaCreateBuffer() and vmaCreateImage()
+    aVmaAllocInfo.flags |= VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT;
+  }
+
+  VkResult aRes = vmaCreateAllocator (&aVmaAllocInfo, &myVmaAllocator);
+  if (aRes != VK_SUCCESS)
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString("Vulkan_DeviceMemoryAllocator, unable to create memory allocator: ") + Vulkan_Device::FormatVkError (aRes));
+    release();
+    return false;
+  }
+
+  return true;
+}
+
+// =======================================================================
+// function : memoryRegionInfo
+// purpose  :
+// =======================================================================
+Vulkan_DeviceMemoryInfo Vulkan_DeviceMemoryAllocator::memoryRegionInfo (const Vulkan_DeviceMemory& theMem) const
+{
+  Vulkan_DeviceMemoryInfo anInfo;
+  if (myVmaAllocator != NULL)
+  {
+    VmaAllocationInfo anAllocInfo = {};
+    vmaGetAllocationInfo (myVmaAllocator, (VmaAllocation )theMem.myOpaque, &anAllocInfo);
+
+    anInfo.DeviceMemory = anAllocInfo.deviceMemory;
+    anInfo.Offset = anAllocInfo.offset;
+    anInfo.Size   = anAllocInfo.size;
+  }
+  else
+  {
+    anInfo.DeviceMemory = (VkDeviceMemory )theMem.myOpaque;
+    anInfo.Offset = 0;
+    anInfo.Size   = 0;
+  }
+  return anInfo;
+}
+
+// =======================================================================
+// function : memoryRegionFree
+// purpose  :
+// =======================================================================
+void Vulkan_DeviceMemoryAllocator::memoryRegionFree (Vulkan_DeviceMemory& theMem)
+{
+  if (theMem.myOpaque != NULL)
+  {
+    if (myVmaAllocator != NULL)
+    {
+      vmaFreeMemory (myVmaAllocator, (VmaAllocation )theMem.myOpaque);
+    }
+    else
+    {
+      vkFreeMemory (myDevice->Device(), (VkDeviceMemory )theMem.myOpaque, myDevice->HostAllocator());
+    }
+    theMem.myOpaque = NULL;
+  }
+}
+
+// =======================================================================
+// function : Allocate
+// purpose  :
+// =======================================================================
+Handle(Vulkan_DeviceMemory) Vulkan_DeviceMemoryAllocator::Allocate (const VkMemoryRequirements& theReqs,
+                                                                    Vulkan_DeviceMemoryUsage theUsage)
+{
+  if (myVmaAllocator == NULL)
+  {
+    VkDeviceMemory aVkDevMem = myDevice->allocateDeviceMemory (theReqs);
+    if (aVkDevMem == NULL)
+    {
+      return Handle(Vulkan_DeviceMemory)();
+    }
+    Handle(Vulkan_DeviceMemory) aDevMem = new Vulkan_DeviceMemory (NULL, aVkDevMem);
+    return aDevMem;
+  }
+
+  VmaAllocation aVmaAlloc = NULL;
+  VmaAllocationCreateInfo anAllocCreateInfo = {};
+  anAllocCreateInfo.usage = memUsageOcctToVma (theUsage);
+
+  VmaAllocationInfo anAllocInfo = {};
+  VkResult aRes = vmaAllocateMemory (myVmaAllocator, &theReqs, &anAllocCreateInfo, &aVmaAlloc, &anAllocInfo);
+  if (aRes != VK_SUCCESS)
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_DeviceMemoryAllocator, failed to allocate device memory [")
+                                       + int(theReqs.size) + "]:" + Vulkan_Device::FormatVkError (aRes), Message_Fail);
+    return Handle(Vulkan_DeviceMemory)();
+  }
+
+  Handle(Vulkan_DeviceMemory) aDevMem = new Vulkan_DeviceMemory (this, aVmaAlloc);
+  return aDevMem;
+}
diff --git a/src/Vulkan/Vulkan_DeviceMemoryAllocator.hxx b/src/Vulkan/Vulkan_DeviceMemoryAllocator.hxx
new file mode 100644 (file)
index 0000000..91e8597
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_DeviceMemoryAllocator_HeaderFile
+#define _Vulkan_DeviceMemoryAllocator_HeaderFile
+
+#include <Vulkan_Object.hxx>
+
+VK_DEFINE_HANDLE(VmaAllocator)
+class Vulkan_DeviceMemory;
+struct Vulkan_DeviceMemoryInfo;
+
+enum Vulkan_DeviceMemoryUsage
+{
+  Vulkan_DeviceMemoryUsage_UNKNOWN = -1, //!< unknown memory usage
+  Vulkan_DeviceMemoryUsage_GpuOnly = 0,  //!< memory to be used on device only
+  Vulkan_DeviceMemoryUsage_CpuOnly,      //!< memory to be mappable on host
+  Vulkan_DeviceMemoryUsage_CpuToGpu,     //!< memory that is both mappable on host and preferably fast to access by GPU
+  Vulkan_DeviceMemoryUsage_GpuToCpu,     //!< memory mappable on host and cached
+};
+
+//! This class defines a memory allocator for device memory.
+//! It is expected to be created by Vulkan_Device itself.
+class Vulkan_DeviceMemoryAllocator : public Standard_Transient
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_DeviceMemoryAllocator, Standard_Transient)
+  friend class Vulkan_DeviceMemory;
+  friend class Vulkan_Device;
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_DeviceMemoryAllocator();
+
+  //! Allocate new memory region.
+  Handle(Vulkan_DeviceMemory) Allocate (const VkMemoryRequirements& theReqs,
+                                        Vulkan_DeviceMemoryUsage theUsage);
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_DeviceMemoryAllocator();
+
+  //! Create the object.
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice,
+                               bool toUseDedicatedAllocs);
+
+  //! Release the object.
+  void release() { releaseAllocator(); }
+
+  //! Release the object.
+  Standard_EXPORT void releaseAllocator();
+
+  //! Return memory region information.
+  Standard_EXPORT Vulkan_DeviceMemoryInfo memoryRegionInfo (const Vulkan_DeviceMemory& theMem) const;
+
+  //! Release memory region.
+  Standard_EXPORT void memoryRegionFree (Vulkan_DeviceMemory& theMem);
+
+protected:
+
+  VmaAllocator   myVmaAllocator;
+  Vulkan_Device* myDevice;
+
+};
+
+#endif // _Vulkan_DeviceMemoryAllocator_HeaderFile
diff --git a/src/Vulkan/Vulkan_Fence.cxx b/src/Vulkan/Vulkan_Fence.cxx
new file mode 100644 (file)
index 0000000..071225a
--- /dev/null
@@ -0,0 +1,132 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_Fence.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Fence, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_Fence
+// purpose  :
+// =======================================================================
+Vulkan_Fence::Vulkan_Fence()
+: myVkFence (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_Fence
+// purpose  :
+// =======================================================================
+Vulkan_Fence::~Vulkan_Fence()
+{
+  releaseFence();
+}
+
+// =======================================================================
+// function : releaseFence
+// purpose  :
+// =======================================================================
+void Vulkan_Fence::releaseFence()
+{
+  if (myVkFence != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_Fence");
+    vkDestroyFence (myDevice->Device(), myVkFence, myDevice->HostAllocator());
+    myVkFence = NULL;
+  }
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_Fence::Create (const Handle(Vulkan_Device)& theDevice)
+{
+  if (myVkFence != NULL
+   && myDevice == theDevice)
+  {
+    return true;
+  }
+
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+
+  VkFenceCreateInfo aVkFenceInfo;
+  aVkFenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+  aVkFenceInfo.pNext = NULL;
+  aVkFenceInfo.flags = 0;
+
+  VkResult aRes = vkCreateFence (theDevice->Device(), &aVkFenceInfo, theDevice->HostAllocator(), &myVkFence);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create fence", aRes);
+    return false;
+  }
+
+  return true;
+}
+
+// =======================================================================
+// function : Wait
+// purpose  :
+// =======================================================================
+bool Vulkan_Fence::Wait()
+{
+  if (myVkFence == NULL)
+  {
+    return false;
+  }
+
+  VkResult aRes = vkWaitForFences (myDevice->Device(), 1, &myVkFence, VK_TRUE, UINT64_MAX);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailure ("failed to wait for fence", aRes);
+    return false;
+  }
+  return true;
+}
+
+// =======================================================================
+// function : Reset
+// purpose  :
+// =======================================================================
+bool Vulkan_Fence::Reset()
+{
+  if (myVkFence == NULL)
+  {
+    return false;
+  }
+
+  VkResult aRes = vkResetFences (myDevice->Device(), 1, &myVkFence);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailure ("failed to reset fence", aRes);
+    return false;
+  }
+  return true;
+}
diff --git a/src/Vulkan/Vulkan_Fence.hxx b/src/Vulkan/Vulkan_Fence.hxx
new file mode 100644 (file)
index 0000000..c60ab66
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Fence_HeaderFile
+#define _Vulkan_Fence_HeaderFile
+
+#include <Vulkan_Object.hxx>
+
+//! This class defines an Vulkan fence.
+class Vulkan_Fence : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Fence, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_Fence();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_Fence();
+
+  //! Return object.
+  VkFence Fence() const { return myVkFence; }
+
+  //! Create the object, @sa vkCreateFence().
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice);
+
+  //! Wait for the fence, @sa vkWaitForFences().
+  Standard_EXPORT bool Wait();
+
+  //! Reset the fence, @sa vkResetFences().
+  Standard_EXPORT bool Reset();
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releaseFence(); }
+
+  //! Release the object, @sa vkDestroyFence().
+  Standard_EXPORT void releaseFence();
+
+protected:
+
+  VkFence myVkFence;
+
+};
+
+#endif // _Vulkan_Fence_HeaderFile
diff --git a/src/Vulkan/Vulkan_ForwardDecl.hxx b/src/Vulkan/Vulkan_ForwardDecl.hxx
new file mode 100644 (file)
index 0000000..010d2e5
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_ForwardDecl_HeaderFile
+#define _Vulkan_ForwardDecl_HeaderFile
+
+#include <Standard_TypeDef.hxx>
+
+#ifndef VK_DEFINE_HANDLE
+  #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
+
+  #if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE)
+  #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+    #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
+  #else
+    #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
+  #endif
+  #endif
+
+  VK_DEFINE_HANDLE(VkInstance)
+  VK_DEFINE_HANDLE(VkPhysicalDevice)
+  VK_DEFINE_HANDLE(VkDevice)
+  VK_DEFINE_HANDLE(VkQueue)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)
+  VK_DEFINE_HANDLE(VkCommandBuffer)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)
+
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
+  VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR)
+
+  struct VkAllocationCallbacks;
+  struct VkMemoryRequirements;
+  struct VkPhysicalDeviceMemoryProperties;
+  struct VkSurfaceFormatKHR;
+
+  typedef uint64_t VkDeviceSize;
+#endif
+
+#endif // _Vulkan_ForwardDecl_HeaderFile
diff --git a/src/Vulkan/Vulkan_FrameBuffer.cxx b/src/Vulkan/Vulkan_FrameBuffer.cxx
new file mode 100644 (file)
index 0000000..cb7d045
--- /dev/null
@@ -0,0 +1,123 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_FrameBuffer.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_Image.hxx>
+#include <Vulkan_RenderPass.hxx>
+#include <Vulkan_Surface.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_FrameBuffer, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_FrameBuffer
+// purpose  :
+// =======================================================================
+Vulkan_FrameBuffer::Vulkan_FrameBuffer()
+: myVkFramebuffer (NULL),
+  myVkImageView (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_FrameBuffer
+// purpose  :
+// =======================================================================
+Vulkan_FrameBuffer::~Vulkan_FrameBuffer()
+{
+  releaseBuffer();
+}
+
+// =======================================================================
+// function : releaseBuffer
+// purpose  :
+// =======================================================================
+void Vulkan_FrameBuffer::releaseBuffer()
+{
+  if (myVkFramebuffer != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_FrameBuffer");
+    vkDestroyFramebuffer (myDevice->Device(), myVkFramebuffer, myDevice->HostAllocator());
+    myVkFramebuffer = NULL;
+  }
+  myRenderPass.Nullify();
+  myDepth.Nullify();
+  mySurface.Nullify();
+  myDevice.Nullify();
+  myVkImageView = NULL;
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_FrameBuffer::Create (const Handle(Vulkan_RenderPass)& theRenderPass,
+                                 const Handle(Vulkan_Surface)& theSurface,
+                                 const uint32_t theChainIndex)
+{
+  if (theRenderPass.IsNull()
+   || theSurface.IsNull())
+  {
+    Release();
+    return false;
+  }
+
+  const VkImageView anImageView = theSurface->ImageViews()[theChainIndex];
+  if (myRenderPass == theRenderPass
+   && mySurface == theSurface
+   && myVkImageView == anImageView
+   && myDepth == theSurface->DepthImage()
+   && mySize == theSurface->Size())
+  {
+    return true;
+  }
+
+  Release();
+  myRenderPass = theRenderPass;
+  mySurface = theSurface;
+  myDepth   = theSurface->DepthImage();
+  myDevice  = theRenderPass->Device();
+  myVkImageView = anImageView;
+  mySize = theSurface->Size();
+
+  VkFramebufferCreateInfo aVkFboInfo = {};
+  const VkImageView aVkImageViews[2] =
+  {
+    anImageView,
+    !myDepth.IsNull() ? myDepth->ImageView() : NULL,
+  };
+  aVkFboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+  aVkFboInfo.pNext = NULL;
+  aVkFboInfo.flags = 0;
+  aVkFboInfo.renderPass = theRenderPass->RenderPass();
+  aVkFboInfo.attachmentCount = 2;
+  aVkFboInfo.pAttachments = aVkImageViews;
+  aVkFboInfo.width  = theSurface->Size().x();
+  aVkFboInfo.height = theSurface->Size().y();
+  aVkFboInfo.layers = 1;
+
+  VkResult aRes = vkCreateFramebuffer (myDevice->Device(), &aVkFboInfo, myDevice->HostAllocator(), &myVkFramebuffer);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create framebuffer", aRes);
+    return false;
+  }
+
+  return true;
+}
diff --git a/src/Vulkan/Vulkan_FrameBuffer.hxx b/src/Vulkan/Vulkan_FrameBuffer.hxx
new file mode 100644 (file)
index 0000000..046b29b
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_FrameBuffer_HeaderFile
+#define _Vulkan_FrameBuffer_HeaderFile
+
+#include <Graphic3d_Vec2.hxx>
+#include <Vulkan_Object.hxx>
+
+class Vulkan_Image;
+class Vulkan_RenderPass;
+class Vulkan_Surface;
+
+//! This class defines an Vulkan frame buffer.
+class Vulkan_FrameBuffer : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_FrameBuffer, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_FrameBuffer();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_FrameBuffer();
+
+  //! Return object.
+  VkFramebuffer FrameBuffer() const { return myVkFramebuffer; }
+
+  //! Create the object, @sa vkCreateFramebuffer().
+  Standard_EXPORT bool Create (const Handle(Vulkan_RenderPass)& theRenderPass,
+                               const Handle(Vulkan_Surface)& theSurface,
+                               const uint32_t theChainIndex);
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releaseBuffer(); }
+
+  //! Release the object, @sa vkDestroyFramebuffer().
+  Standard_EXPORT void releaseBuffer();
+
+protected:
+
+  Handle(Vulkan_RenderPass) myRenderPass;
+  Handle(Vulkan_Surface)    mySurface;
+  Handle(Vulkan_Image)      myDepth;
+  VkFramebuffer   myVkFramebuffer;
+  VkImageView     myVkImageView;
+  Graphic3d_Vec2u mySize;
+
+};
+
+#endif // _Vulkan_FrameBuffer_HeaderFile
diff --git a/src/Vulkan/Vulkan_FrameStats.cxx b/src/Vulkan/Vulkan_FrameStats.cxx
new file mode 100644 (file)
index 0000000..574c066
--- /dev/null
@@ -0,0 +1,316 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_FrameStats.hxx>
+
+#include <Vulkan_View.hxx>
+#include <Vulkan_Structure.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_FrameStats, Graphic3d_FrameStats)
+
+namespace
+{
+  //! Return estimated data size.
+  /**static Standard_Size estimatedDataSize (const Handle(OpenGl_Resource)& theRes)
+  {
+    return !theRes.IsNull() ? theRes->EstimatedDataSize() : 0;
+  }*/
+}
+
+// =======================================================================
+// function : Vulkan_FrameStats
+// purpose  :
+// =======================================================================
+Vulkan_FrameStats::Vulkan_FrameStats()
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_FrameStats
+// purpose  :
+// =======================================================================
+Vulkan_FrameStats::~Vulkan_FrameStats()
+{
+  //
+}
+
+// =======================================================================
+// function : IsFrameUpdated
+// purpose  :
+// =======================================================================
+bool Vulkan_FrameStats::IsFrameUpdated (Handle(Vulkan_FrameStats)& thePrev) const
+{
+  const Graphic3d_FrameStatsData& aFrame = LastDataFrame();
+  if (thePrev.IsNull())
+  {
+    thePrev = new Vulkan_FrameStats();
+  }
+  // check just a couple of major counters
+  else if (myLastFrameIndex == thePrev->myLastFrameIndex
+        && Abs (aFrame.FrameRate()    - thePrev->myCountersTmp.FrameRate())    <= 0.001
+        && Abs (aFrame.FrameRateCpu() - thePrev->myCountersTmp.FrameRateCpu()) <= 0.001
+        && aFrame[Graphic3d_FrameStatsCounter_NbLayers]           == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbLayers]
+        && aFrame[Graphic3d_FrameStatsCounter_NbLayersNotCulled]  == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbLayersNotCulled]
+        && aFrame[Graphic3d_FrameStatsCounter_NbStructs]          == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbStructs]
+        && aFrame[Graphic3d_FrameStatsCounter_NbStructsNotCulled] == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbStructsNotCulled])
+  {
+    return false;
+  }
+
+  thePrev->myLastFrameIndex = myLastFrameIndex;
+  thePrev->myCountersTmp = aFrame;
+  return true;
+}
+
+// =======================================================================
+// function : updateStatistics
+// purpose  :
+// =======================================================================
+void Vulkan_FrameStats::updateStatistics (const Handle(Graphic3d_CView)& theView,
+                                          bool theIsImmediateOnly)
+{
+  const Vulkan_View* aView = dynamic_cast<const Vulkan_View*> (theView.get());
+  if (aView == NULL)
+  {
+    myCounters.SetValue (myLastFrameIndex, myCountersTmp);
+    myCountersTmp.Reset();
+    return;
+  }
+
+  const Graphic3d_RenderingParams::PerfCounters aBits = theView->RenderingParams().CollectedStats;
+  const Standard_Boolean toCountMem     = (aBits & Graphic3d_RenderingParams::PerfCounters_EstimMem)  != 0;
+  const Standard_Boolean toCountTris    = (aBits & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0
+                                       || (aBits & Graphic3d_RenderingParams::PerfCounters_Points)    != 0;
+  const Standard_Boolean toCountElems   = (aBits & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0 || toCountTris || toCountMem;
+  const Standard_Boolean toCountGroups  = (aBits & Graphic3d_RenderingParams::PerfCounters_Groups)      != 0 || toCountElems;
+  const Standard_Boolean toCountStructs = (aBits & Graphic3d_RenderingParams::PerfCounters_Structures)  != 0
+                                       || (aBits & Graphic3d_RenderingParams::PerfCounters_Layers)      != 0 || toCountGroups;
+
+  /// TODO
+  ///myCountersTmp[Graphic3d_FrameStatsCounter_NbLayers] = aView->LayerList().Layers().Size();
+  if (toCountStructs
+   || (aBits & Graphic3d_RenderingParams::PerfCounters_Layers)    != 0)
+  {
+    const Standard_Integer aViewId = aView->Identification();
+    /// TODO
+    /*for (OpenGl_SequenceOfLayers::Iterator aLayerIter (aView->LayerList().Layers()); aLayerIter.More(); aLayerIter.Next())
+    {
+      const Handle(OpenGl_Layer)& aLayer = aLayerIter.Value();
+      myCountersTmp[Graphic3d_FrameStatsCounter_NbStructs] += aLayer->NbStructures();
+      if (theIsImmediateOnly && !aLayer->LayerSettings().IsImmediate())
+      {
+        continue;
+      }
+
+      if (!aLayer->IsCulled())
+      {
+        ++myCountersTmp[Graphic3d_FrameStatsCounter_NbLayersNotCulled];
+      }
+      myCountersTmp[Graphic3d_FrameStatsCounter_NbStructsNotCulled] += aLayer->NbStructuresNotCulled();
+      if (toCountGroups)
+      {
+        updateStructures (aViewId, aLayer->CullableStructuresBVH().Structures(), toCountElems, toCountTris, toCountMem);
+        updateStructures (aViewId, aLayer->CullableTrsfPersStructuresBVH().Structures(), toCountElems, toCountTris, toCountMem);
+        updateStructures (aViewId, aLayer->NonCullableStructures(), toCountElems, toCountTris, toCountMem);
+      }
+    }*/
+  }
+  if (toCountMem)
+  {
+    // TODO
+    /**for (OpenGl_Context::OpenGl_ResourcesMap::Iterator aResIter (aView->GlWindow()->GetGlContext()->SharedResources());
+         aResIter.More(); aResIter.Next())
+    {
+      myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesTextures] += aResIter.Value()->EstimatedDataSize();
+    }
+
+    {
+      Standard_Size& aMemFbos = myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesFbos];
+      // main FBOs
+      aMemFbos += estimatedDataSize (aView->myMainSceneFbos[0]);
+      aMemFbos += estimatedDataSize (aView->myMainSceneFbos[1]);
+      aMemFbos += estimatedDataSize (aView->myImmediateSceneFbos[0]);
+      aMemFbos += estimatedDataSize (aView->myImmediateSceneFbos[1]);
+      // OIT FBOs
+      aMemFbos += estimatedDataSize (aView->myMainSceneFbosOit[0]);
+      aMemFbos += estimatedDataSize (aView->myMainSceneFbosOit[1]);
+      aMemFbos += estimatedDataSize (aView->myImmediateSceneFbosOit[0]);
+      aMemFbos += estimatedDataSize (aView->myImmediateSceneFbosOit[1]);
+      // dump FBO
+      aMemFbos += estimatedDataSize (aView->myFBO);
+      // RayTracing FBO
+      aMemFbos += estimatedDataSize (aView->myOpenGlFBO);
+      aMemFbos += estimatedDataSize (aView->myOpenGlFBO2);
+      aMemFbos += estimatedDataSize (aView->myRaytraceFBO1[0]);
+      aMemFbos += estimatedDataSize (aView->myRaytraceFBO1[1]);
+      aMemFbos += estimatedDataSize (aView->myRaytraceFBO2[0]);
+      aMemFbos += estimatedDataSize (aView->myRaytraceFBO2[1]);
+      // also RayTracing
+      aMemFbos += estimatedDataSize (aView->myRaytraceOutputTexture[0]);
+      aMemFbos += estimatedDataSize (aView->myRaytraceOutputTexture[1]);
+      aMemFbos += estimatedDataSize (aView->myRaytraceVisualErrorTexture[0]);
+      aMemFbos += estimatedDataSize (aView->myRaytraceVisualErrorTexture[1]);
+      aMemFbos += estimatedDataSize (aView->myRaytraceTileOffsetsTexture[0]);
+      aMemFbos += estimatedDataSize (aView->myRaytraceTileOffsetsTexture[1]);
+      aMemFbos += estimatedDataSize (aView->myRaytraceTileSamplesTexture[0]);
+      aMemFbos += estimatedDataSize (aView->myRaytraceTileSamplesTexture[1]);
+    }*/
+  }
+}
+
+// =======================================================================
+// function : updateStructures
+// purpose  :
+// =======================================================================
+void Vulkan_FrameStats::updateStructures (Standard_Integer theViewId,
+                                          const NCollection_IndexedMap<const Graphic3d_CStructure*>& theStructures,
+                                          Standard_Boolean theToCountElems,
+                                          Standard_Boolean theToCountTris,
+                                          Standard_Boolean theToCountMem)
+{
+  for (Vulkan_Structure::StructIterator aStructIter (theStructures); aStructIter.More(); aStructIter.Next())
+  {
+    const Vulkan_Structure* aStruct = aStructIter.Value();
+    const bool isStructHidden = aStruct->IsCulled()
+                            || !aStruct->IsVisible (theViewId);
+    for (; aStruct != NULL; aStruct = aStruct->InstancedStructure())
+    {
+      if (isStructHidden)
+      {
+        if (theToCountMem)
+        {
+          for (Vulkan_Structure::GroupIterator aGroupIter (aStruct->Groups()); aGroupIter.More(); aGroupIter.Next())
+          {
+            const Vulkan_Group* aGroup = aGroupIter.Value();
+            // TODO
+            /**for (const OpenGl_ElementNode* aNodeIter = aGroup->FirstNode(); aNodeIter != NULL; aNodeIter = aNodeIter->next)
+            {
+              if (const OpenGl_PrimitiveArray* aPrim = dynamic_cast<const OpenGl_PrimitiveArray*> (aNodeIter->elem))
+              {
+                myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesGeom] += estimatedDataSize (aPrim->AttributesVbo());
+                myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesGeom] += estimatedDataSize (aPrim->IndexVbo());
+              }
+            }*/
+          }
+        }
+        continue;
+      }
+
+      myCountersTmp[Graphic3d_FrameStatsCounter_NbGroupsNotCulled] += aStruct->Groups().Size();
+      if (!theToCountElems)
+      {
+        continue;
+      }
+
+      for (Vulkan_Structure::GroupIterator aGroupIter (aStruct->Groups()); aGroupIter.More(); aGroupIter.Next())
+      {
+        const Vulkan_Group* aGroup = aGroupIter.Value();
+        // TODO
+        /**for (const OpenGl_ElementNode* aNodeIter = aGroup->FirstNode(); aNodeIter != NULL; aNodeIter = aNodeIter->next)
+        {
+          if (const OpenGl_PrimitiveArray* aPrim = dynamic_cast<const OpenGl_PrimitiveArray*> (aNodeIter->elem))
+          {
+            ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsNotCulled];
+            if (theToCountMem)
+            {
+              myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesGeom] += estimatedDataSize (aPrim->AttributesVbo());
+              myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesGeom] += estimatedDataSize (aPrim->IndexVbo());
+            }
+
+            if (aPrim->IsFillDrawMode())
+            {
+              ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsFillNotCulled];
+              if (!theToCountTris)
+              {
+                continue;
+              }
+
+              const Handle(OpenGl_VertexBuffer)& anAttribs = aPrim->AttributesVbo();
+              if (anAttribs.IsNull()
+              || !anAttribs->IsValid())
+              {
+                continue;
+              }
+
+              const Handle(OpenGl_VertexBuffer)& anIndices = aPrim->IndexVbo();
+              const Standard_Integer aNbIndices = !anIndices.IsNull() ? anIndices->GetElemsNb() : anAttribs->GetElemsNb();
+              const Standard_Integer aNbBounds  = !aPrim->Bounds().IsNull() ? aPrim->Bounds()->NbBounds : 1;
+              switch (aPrim->DrawMode())
+              {
+                case GL_TRIANGLES:
+                {
+                  myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += aNbIndices / 3;
+                  break;
+                }
+                case GL_TRIANGLE_STRIP:
+                case GL_TRIANGLE_FAN:
+                {
+                  myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += aNbIndices - 2 * aNbBounds;
+                  break;
+                }
+                case GL_TRIANGLES_ADJACENCY:
+                {
+                  myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += aNbIndices / 6;
+                  break;
+                }
+                case GL_TRIANGLE_STRIP_ADJACENCY:
+                {
+                  myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += aNbIndices - 4 * aNbBounds;
+                  break;
+                }
+              #if !defined(GL_ES_VERSION_2_0)
+                case GL_QUADS:
+                {
+                  myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += aNbIndices / 2;
+                  break;
+                }
+                case GL_QUAD_STRIP:
+                {
+                  myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += (aNbIndices / 2 - aNbBounds) * 2;
+                  break;
+                }
+              #endif
+              }
+            }
+            else if (aPrim->DrawMode() == GL_POINTS)
+            {
+              ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsPointNotCulled];
+              if (theToCountTris)
+              {
+                const Handle(OpenGl_VertexBuffer)& anAttribs = aPrim->AttributesVbo();
+                if (!anAttribs.IsNull()
+                  && anAttribs->IsValid())
+                {
+                  const Handle(OpenGl_VertexBuffer)& anIndices = aPrim->IndexVbo();
+                  const Standard_Integer aNbIndices = !anIndices.IsNull() ? anIndices->GetElemsNb() : anAttribs->GetElemsNb();
+                  myCountersTmp[Graphic3d_FrameStatsCounter_NbPointsNotCulled] += aNbIndices;
+                }
+              }
+            }
+            else
+            {
+              ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsLineNotCulled];
+            }
+          }
+          else if (const OpenGl_Text* aText = dynamic_cast<const OpenGl_Text*> (aNodeIter->elem))
+          {
+            (void )aText;
+            ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsNotCulled];
+            ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsTextNotCulled];
+          }
+        }*/
+      }
+    }
+  }
+}
diff --git a/src/Vulkan/Vulkan_FrameStats.hxx b/src/Vulkan/Vulkan_FrameStats.hxx
new file mode 100644 (file)
index 0000000..1f22325
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_FrameStats_HeaderFile
+#define _Vulkan_FrameStats_HeaderFile
+
+#include <Graphic3d_FrameStats.hxx>
+#include <NCollection_IndexedMap.hxx>
+
+class Graphic3d_CStructure;
+
+//! Class storing the frame statistics.
+class Vulkan_FrameStats : public Graphic3d_FrameStats
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_FrameStats, Graphic3d_FrameStats)
+public:
+
+  //! Default constructor.
+  Standard_EXPORT Vulkan_FrameStats();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_FrameStats();
+
+public:
+
+  //! Copy stats values into another instance (create new instance, if not exists).
+  //! The main use of this method is to track changes in statistics (e.g. in conjunction with IsEqual() method).
+  //! @return TRUE if frame data has been changed so that the presentation should be updated
+  Standard_EXPORT virtual bool IsFrameUpdated (Handle(Vulkan_FrameStats)& thePrev) const;
+
+protected:
+
+  //! Method to collect statistics from the View; called by FrameEnd().
+  Standard_EXPORT virtual void updateStatistics (const Handle(Graphic3d_CView)& theView,
+                                                 bool theIsImmediateOnly) Standard_OVERRIDE;
+
+  //! Updates counters for structures.
+  Standard_EXPORT virtual void updateStructures (Standard_Integer theViewId,
+                                                 const NCollection_IndexedMap<const Graphic3d_CStructure*>& theStructures,
+                                                 Standard_Boolean theToCountElems,
+                                                 Standard_Boolean theToCountTris,
+                                                 Standard_Boolean theToCountMem);
+
+};
+
+DEFINE_STANDARD_HANDLE(Vulkan_FrameStats, Graphic3d_FrameStats)
+
+#endif // _Vulkan_FrameStats_HeaderFile
diff --git a/src/Vulkan/Vulkan_GraphicDriver.cxx b/src/Vulkan/Vulkan_GraphicDriver.cxx
new file mode 100644 (file)
index 0000000..d9878b6
--- /dev/null
@@ -0,0 +1,356 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_GraphicDriver.hxx>
+
+#include <Vulkan_Caps.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_View.hxx>
+#include <Vulkan_Structure.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Standard_Version.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_GraphicDriver, Graphic3d_GraphicDriver)
+
+// =======================================================================
+// function : Vulkan_GraphicDriver
+// purpose  :
+// =======================================================================
+Vulkan_GraphicDriver::Vulkan_GraphicDriver (const TCollection_AsciiString& theAppName,
+                                            const uint32_t theAppVersion,
+                                            const Handle(Aspect_DisplayConnection)& theDisp)
+: Graphic3d_GraphicDriver (theDisp),
+  myVkDevice (new Vulkan_Device (theAppName, theAppVersion, "Open CASCADE Technology",
+                                 DefineVersion (OCC_VERSION_MAJOR, OCC_VERSION_MINOR, OCC_VERSION_MAINTENANCE))),
+  myCaps (new Vulkan_Caps()),
+  myMapOfView      (1, NCollection_BaseAllocator::CommonBaseAllocator()),
+  myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator())
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_GraphicDriver
+// purpose  :
+// =======================================================================
+Vulkan_GraphicDriver::~Vulkan_GraphicDriver()
+{
+  ReleaseContext();
+}
+
+// =======================================================================
+// function : ReleaseContext
+// purpose  :
+// =======================================================================
+void Vulkan_GraphicDriver::ReleaseContext()
+{
+  myVkDevice->Release();
+}
+
+// =======================================================================
+// function : InitContext
+// purpose  :
+// =======================================================================
+Standard_Boolean Vulkan_GraphicDriver::InitContext()
+{
+  ReleaseContext();
+  return myVkDevice->Init (myCaps);
+}
+
+// =======================================================================
+// function : InquireLimit
+// purpose  :
+// =======================================================================
+Standard_Integer Vulkan_GraphicDriver::InquireLimit (const Graphic3d_TypeOfLimit theType) const
+{
+  return 0;
+}
+
+// =======================================================================
+// function : DefaultTextHeight
+// purpose  :
+// =======================================================================
+Standard_ShortReal Vulkan_GraphicDriver::DefaultTextHeight() const
+{
+  return 16.;
+}
+
+// =======================================================================
+// function : MemoryInfo
+// purpose  :
+// =======================================================================
+Standard_Boolean Vulkan_GraphicDriver::MemoryInfo (Standard_Size&           theFreeBytes,
+                                                   TCollection_AsciiString& theInfo) const
+{
+  return false;
+}
+
+// =======================================================================
+// function : TextSize
+// purpose  :
+// =======================================================================
+void Vulkan_GraphicDriver::TextSize (const Handle(Graphic3d_CView)& theView,
+                                     const Standard_CString         theText,
+                                     const Standard_ShortReal       theHeight,
+                                     Standard_ShortReal&            theWidth,
+                                     Standard_ShortReal&            theAscent,
+                                     Standard_ShortReal&            theDescent) const
+{
+}
+
+//=======================================================================
+//function : AddZLayer
+//purpose  :
+//=======================================================================
+void Vulkan_GraphicDriver::AddZLayer (const Graphic3d_ZLayerId theLayerId)
+{
+  if (theLayerId < 1)
+  {
+    Standard_ASSERT_RAISE (theLayerId > 0, "Vulkan_GraphicDriver::AddZLayer, negative and zero IDs are reserved");
+  }
+
+  myLayerIds.Add (theLayerId);
+
+  // Default z-layer settings
+  myMapOfZLayerSettings.Bind (theLayerId, Graphic3d_ZLayerSettings());
+  addZLayerIndex (theLayerId);
+
+  // Add layer to all views
+  for (NCollection_Map<Handle(Vulkan_View)>::Iterator aViewIt (myMapOfView); aViewIt.More(); aViewIt.Next())
+  {
+    aViewIt.Value()->AddZLayer (theLayerId);
+  }
+}
+
+//=======================================================================
+//function : RemoveZLayer
+//purpose  :
+//=======================================================================
+void Vulkan_GraphicDriver::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
+{
+  Standard_ASSERT_RAISE (theLayerId > 0,
+                         "Vulkan_GraphicDriver::AddZLayer, negative and zero IDs are reserved and can not be removed");
+
+  Standard_ASSERT_RAISE (myLayerIds.Contains (theLayerId),
+                         "Vulkan_GraphicDriver::RemoveZLayer, Layer with theLayerId does not exist");
+
+  // Remove layer from all of the views
+  for (NCollection_Map<Handle(Vulkan_View)>::Iterator aViewIt (myMapOfView); aViewIt.More(); aViewIt.Next())
+  {
+    aViewIt.Value()->RemoveZLayer (theLayerId);
+  }
+
+  // Unset Z layer for all of the structures.
+  for (NCollection_DataMap<Standard_Integer, Vulkan_Structure*>::Iterator aStructIt (myMapOfStructure); aStructIt.More(); aStructIt.Next())
+  {
+    Vulkan_Structure* aStruct = aStructIt.ChangeValue();
+    if (aStruct->ZLayer() == theLayerId)
+    {
+      aStruct->SetZLayer (Graphic3d_ZLayerId_Default);
+    }
+  }
+
+  // Remove index
+  for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
+  {
+    if (aLayerIt.Value() == theLayerId)
+    {
+      myLayerSeq.Remove (aLayerIt);
+      break;
+    }
+  }
+
+  myMapOfZLayerSettings.UnBind (theLayerId);
+  myLayerIds.Remove  (theLayerId);
+}
+
+//=======================================================================
+//function : SetZLayerSettings
+//purpose  :
+//=======================================================================
+void Vulkan_GraphicDriver::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
+                                              const Graphic3d_ZLayerSettings& theSettings)
+{
+  base_type::SetZLayerSettings (theLayerId, theSettings);
+
+  // Change Z layer settings in all managed views
+  for (NCollection_Map<Handle(Vulkan_View)>::Iterator aViewIt (myMapOfView); aViewIt.More(); aViewIt.Next())
+  {
+    aViewIt.Value()->SetZLayerSettings (theLayerId, theSettings);
+  }
+}
+
+// =======================================================================
+// function : Structure
+// purpose  :
+// =======================================================================
+Handle(Graphic3d_CStructure) Vulkan_GraphicDriver::CreateStructure (const Handle(Graphic3d_StructureManager)& theManager)
+{
+  Handle(Vulkan_Structure) aStructure = new Vulkan_Structure (theManager);
+  myMapOfStructure.Bind (aStructure->Id, aStructure.get());
+  return aStructure;
+}
+
+// =======================================================================
+// function : Structure
+// purpose  :
+// =======================================================================
+void Vulkan_GraphicDriver::RemoveStructure (Handle(Graphic3d_CStructure)& theCStructure)
+{
+  Vulkan_Structure* aStructure = NULL;
+  if (!myMapOfStructure.Find (theCStructure->Id, aStructure))
+  {
+    return;
+  }
+
+  myMapOfStructure.UnBind (theCStructure->Id);
+  /// TODO aStructure->Release (GetSharedContext());
+  theCStructure.Nullify();
+}
+
+// =======================================================================
+// function : View
+// purpose  :
+// =======================================================================
+Handle(Graphic3d_CView) Vulkan_GraphicDriver::CreateView (const Handle(Graphic3d_StructureManager)& theMgr)
+{
+  Handle(Vulkan_View) aView = new Vulkan_View (theMgr, this);
+
+  myMapOfView.Add (aView);
+
+  for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
+  {
+    const Graphic3d_ZLayerId        aLayerID  = aLayerIt.Value();
+    const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerID);
+    aView->AddZLayer         (aLayerID);
+    aView->SetZLayerSettings (aLayerID, aSettings);
+  }
+
+  return aView;
+}
+
+// =======================================================================
+// function : RemoveView
+// purpose  :
+// =======================================================================
+void Vulkan_GraphicDriver::RemoveView (const Handle(Graphic3d_CView)& theView)
+{
+  /**Handle(Vulkan_Context) aCtx = GetSharedContext();
+  Handle(Vulkan_View) aView   = Handle(Vulkan_View)::DownCast (theView);
+  if (aView.IsNull())
+  {
+    return;
+  }
+
+  if (!myMapOfView.Remove (aView))
+  {
+    return;
+  }
+
+  Handle(Vulkan_Window) aWindow = aView->GlWindow();
+  if (!aWindow.IsNull()
+    && aWindow->GetGlContext()->MakeCurrent())
+  {
+    aCtx = aWindow->GetGlContext();
+  }
+  else
+  {
+    // try to hijack another context if any
+    const Handle(Vulkan_Context)& anOtherCtx = GetSharedContext();
+    if (!anOtherCtx.IsNull()
+      && anOtherCtx != aWindow->GetGlContext())
+    {
+      aCtx = anOtherCtx;
+      aCtx->MakeCurrent();
+    }
+  }
+
+  aView->ReleaseGlResources (aCtx);
+  if (myMapOfView.IsEmpty())
+  {
+    // The last view removed but some objects still present.
+    // Release GL resources now without object destruction.
+    for (NCollection_DataMap<Standard_Integer, Vulkan_Structure*>::Iterator aStructIt (myMapOfStructure);
+         aStructIt.More (); aStructIt.Next())
+    {
+      Vulkan_Structure* aStruct = aStructIt.ChangeValue();
+      aStruct->ReleaseGlResources (aCtx);
+    }
+
+    if (!myMapOfStructure.IsEmpty())
+    {
+      aView->StructureManager()->SetDeviceLost();
+    }
+  }*/
+}
+
+//=======================================================================
+//function : ViewExists
+//purpose  :
+//=======================================================================
+Standard_Boolean Vulkan_GraphicDriver::ViewExists (const Handle(Aspect_Window)& theWindow,
+                                                   Handle(Graphic3d_CView)& theView)
+{
+  // Parse the list of views to find a view with the specified window
+/*#if defined(_WIN32) && !defined(OCCT_UWP)
+  const Handle(WNT_Window) aWindowToFind = Handle(WNT_Window)::DownCast (theWindow);
+  Aspect_Handle aWindowIdToFind = aWindowToFind->HWindow();
+#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
+  const Handle(Cocoa_Window) aWindowToFind = Handle(Cocoa_Window)::DownCast (theWindow);
+  #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+    UIView* aWindowIdToFind = aWindowToFind->HView();
+  #else
+    NSView* aWindowIdToFind = aWindowToFind->HView();
+  #endif
+#elif defined(__ANDROID__) || defined(__QNX__) || defined(OCCT_UWP)
+  (void )theWindow;
+  int aWindowIdToFind = -1;
+#else
+  const Handle(Xw_Window) aWindowToFind = Handle(Xw_Window)::DownCast (theWindow);
+  int aWindowIdToFind = int (aWindowToFind->XWindow());
+#endif
+  for (NCollection_Map<Handle(Vulkan_View)>::Iterator aViewIt (myMapOfView); aViewIt.More(); aViewIt.Next())
+  {
+    const Handle(Vulkan_View)& aView = aViewIt.Value();
+    if (aView->IsDefined()
+     && aView->IsActive())
+    {
+      const Handle(Aspect_Window) anAspectWindow = aView->Window();
+
+    #if defined(_WIN32) && !defined(OCCT_UWP)
+      const Handle(WNT_Window) aWindow = Handle(WNT_Window)::DownCast (anAspectWindow);
+      Aspect_Handle aWindowIdOfView = aWindow->HWindow();
+    #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
+      const Handle(Cocoa_Window) aWindow = Handle(Cocoa_Window)::DownCast (anAspectWindow);
+      #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+        UIView* aWindowIdOfView = aWindow->HView();
+      #else
+        NSView* aWindowIdOfView = aWindow->HView();
+      #endif
+    #elif defined(__ANDROID__) || defined(__QNX__) || defined(OCCT_UWP)
+      int aWindowIdOfView = 0;
+    #else
+      const Handle(Xw_Window) aWindow = Handle(Xw_Window)::DownCast (anAspectWindow);
+      int aWindowIdOfView = int(aWindow->XWindow());
+    #endif
+      if (aWindowIdOfView == aWindowIdToFind)
+      {
+        theView = aView;
+        return true;
+      }
+    }
+  }*/
+  return false;
+}
diff --git a/src/Vulkan/Vulkan_GraphicDriver.hxx b/src/Vulkan/Vulkan_GraphicDriver.hxx
new file mode 100644 (file)
index 0000000..2e03f5b
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_GraphicDriver_HeaderFile
+#define _Vulkan_GraphicDriver_HeaderFile
+
+#include <Graphic3d_GraphicDriver.hxx>
+
+class Vulkan_Caps;
+class Vulkan_Device;
+class Vulkan_Structure;
+class Vulkan_View;
+class Vulkan_Window;
+
+//! This class defines an Vulkan graphic driver
+class Vulkan_GraphicDriver : public Graphic3d_GraphicDriver
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_GraphicDriver, Graphic3d_GraphicDriver)
+public:
+
+  //! This is VK_MAKE_VERSION() redefinition.
+  //! Note that VK_MAKE_VERSION() uses different bits comparing to OCC_VERSION_HEX.
+  static uint32_t DefineVersion (uint32_t theMajor, uint32_t theMinor, uint32_t thePatch)
+  {
+    return ((theMajor << 22) | (theMinor << 12) | thePatch);
+  }
+
+public:
+
+  //! Constructor.
+  //! @param theAppName application name to be passed to Vulkan
+  //! @param theAppVersion application version to be passed to Vulkan, see DefineVersion() method
+  //! @param theDisp connection to display, required on Linux but optional on other systems
+  Standard_EXPORT Vulkan_GraphicDriver (const TCollection_AsciiString& theAppName,
+                                        const uint32_t theAppVersion,
+                                        const Handle(Aspect_DisplayConnection)& theDisp);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_GraphicDriver();
+
+  //! Release default context.
+  Standard_EXPORT void ReleaseContext();
+
+  //! @return the visualization options
+  Standard_EXPORT const Handle(Vulkan_Caps)& Options() const { return myCaps; }
+
+  //! Perform initialization of default OpenGL context.
+  Standard_EXPORT Standard_Boolean InitContext();
+
+  //! Request limit of graphic resource of specific type.
+  Standard_EXPORT virtual Standard_Integer InquireLimit (const Graphic3d_TypeOfLimit theType) const Standard_OVERRIDE;
+
+public:
+
+  Standard_EXPORT virtual Handle(Graphic3d_CStructure) CreateStructure (const Handle(Graphic3d_StructureManager)& theManager) Standard_OVERRIDE;
+
+  Standard_EXPORT virtual void RemoveStructure (Handle(Graphic3d_CStructure)& theCStructure) Standard_OVERRIDE;
+
+  Standard_EXPORT virtual Handle(Graphic3d_CView) CreateView (const Handle(Graphic3d_StructureManager)& theMgr) Standard_OVERRIDE;
+
+  Standard_EXPORT virtual void RemoveView (const Handle(Graphic3d_CView)& theView) Standard_OVERRIDE;
+
+public:
+
+  Standard_EXPORT virtual void TextSize (const Handle(Graphic3d_CView)& theView,
+                                         const Standard_CString         theText,
+                                         const Standard_ShortReal       theHeight,
+                                         Standard_ShortReal&            theWidth,
+                                         Standard_ShortReal&            theAscent,
+                                         Standard_ShortReal&            theDescent) const Standard_OVERRIDE;
+
+  Standard_EXPORT virtual Standard_ShortReal DefaultTextHeight() const Standard_OVERRIDE;
+
+  Standard_EXPORT virtual Standard_Boolean ViewExists (const Handle(Aspect_Window)& theWindow,
+                                                       Handle(Graphic3d_CView)& theView) Standard_OVERRIDE;
+
+public:
+
+  //! Adds a new top-level z layer with ID theLayerId for all views. Z layers allow drawing structures in higher layers
+  //! in foreground of structures in lower layers. To add a structure to desired layer on display it is necessary to
+  //! set the layer index for the structure. The passed theLayerId should be not less than 0 (reserved for default layers).
+  Standard_EXPORT virtual void AddZLayer (const Graphic3d_ZLayerId theLayerId) Standard_OVERRIDE;
+
+  //! Removes Z layer. All structures displayed at the moment in layer will be displayed in
+  //! default layer (the bottom-level z layer). By default, there are always default
+  //! bottom-level layer that can't be removed.  The passed theLayerId should be not less than 0
+  //! (reserved for default layers that can not be removed).
+  Standard_EXPORT virtual void RemoveZLayer (const Graphic3d_ZLayerId theLayerId) Standard_OVERRIDE;
+
+  //! Sets the settings for a single Z layer.
+  Standard_EXPORT virtual void SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings) Standard_OVERRIDE;
+
+public:
+
+  //! Obsolete method.
+  virtual void EnableVBO (const Standard_Boolean ) Standard_OVERRIDE {}
+
+  //! Returns information about GPU memory usage.
+  //! Please read OpenGl_Context::MemoryInfo() for more description.
+  Standard_EXPORT virtual Standard_Boolean MemoryInfo (Standard_Size&           theFreeBytes,
+                                                       TCollection_AsciiString& theInfo) const Standard_OVERRIDE;
+
+public:
+
+  const Handle(Vulkan_Device)& Device() const { return myVkDevice; }
+
+protected:
+
+  Handle(Vulkan_Device) myVkDevice;
+
+  Handle(Vulkan_Caps)                                      myCaps;
+  NCollection_Map<Handle(Vulkan_View)>                     myMapOfView;
+  NCollection_DataMap<Standard_Integer, Vulkan_Structure*> myMapOfStructure;
+
+};
+
+#endif // _Vulkan_GraphicDriver_HeaderFile
diff --git a/src/Vulkan/Vulkan_Group.cxx b/src/Vulkan/Vulkan_Group.cxx
new file mode 100644 (file)
index 0000000..d2237bf
--- /dev/null
@@ -0,0 +1,337 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_Group.hxx>
+
+#include <Graphic3d_ArrayOfPrimitives.hxx>
+#include <Graphic3d_GroupDefinitionError.hxx>
+#include <Graphic3d_Structure.hxx>
+#include <Vulkan_PrimitiveArray.hxx>
+#include <Vulkan_Structure.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Group, Graphic3d_Group)
+
+namespace
+{
+  //! Render element if it passes the filtering procedure. This method should
+  //! be used for elements which can be used in scope of rendering algorithms.
+  //! E.g. elements of groups during recursive rendering.
+  //! If render filter is null, pure rendering is performed.
+  //! @param theWorkspace [in] the rendering workspace.
+  //! @param theFilter [in] the rendering filter to check whether the element
+  //! should be rendered or not.
+  //! @return True if element passes the check and renders,
+  /*static bool renderFiltered (const Handle(OpenGl_Workspace)& theWorkspace,
+                              OpenGl_Element* theElement)
+  {
+    if (!theWorkspace->ShouldRender (theElement))
+    {
+      return false;
+    }
+
+    theElement->Render (theWorkspace);
+    return true;
+  }*/
+}
+
+// =======================================================================
+// function : Vulkan_Group
+// purpose  :
+// =======================================================================
+Vulkan_Group::Vulkan_Group (const Handle(Graphic3d_Structure)& theStruct)
+: Graphic3d_Group (theStruct)
+  //myAspects(NULL),
+  //myFirst(NULL),
+  //myLast(NULL)
+{
+  const Vulkan_Structure* aStruct = dynamic_cast<Vulkan_Structure* >(myStructure->CStructure().get());
+  if (aStruct == NULL)
+  {
+    throw Graphic3d_GroupDefinitionError("Vulkan_Group should be created by Vulkan_Structure!");
+  }
+}
+
+// =======================================================================
+// function : ~Vulkan_Group
+// purpose  :
+// =======================================================================
+Vulkan_Group::~Vulkan_Group()
+{
+  /// TODO
+  ///Release (Handle(OpenGl_Context)());
+}
+
+// =======================================================================
+// function : SetGroupPrimitivesAspect
+// purpose  :
+// =======================================================================
+void Vulkan_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect)
+{
+  if (IsDeleted())
+  {
+    return;
+  }
+
+  /*if (myAspects == NULL)
+  {
+    myAspects = new OpenGl_Aspects (theAspect);
+  }
+  else
+  {
+    myAspects->SetAspect (theAspect);
+  }*/
+
+  Update();
+}
+
+// =======================================================================
+// function : SetPrimitivesAspect
+// purpose  :
+// =======================================================================
+void Vulkan_Group::SetPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect)
+{
+  /*if (myAspects == NULL)
+  {
+    SetGroupPrimitivesAspect (theAspect);
+    return;
+  }
+  else if (IsDeleted())
+  {
+    return;
+  }
+
+  OpenGl_Aspects* anAspects = new OpenGl_Aspects (theAspect);
+  AddElement (anAspects);*/
+  Update();
+}
+
+// =======================================================================
+// function : SynchronizeAspects
+// purpose  :
+// =======================================================================
+void Vulkan_Group::SynchronizeAspects()
+{
+  /*if (myAspects != NULL)
+  {
+    myAspects->SynchronizeAspects();
+    if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
+    {
+      aStruct->UpdateStateIfRaytracable (Standard_False);
+    }
+  }
+  for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next)
+  {
+    aNode->elem->SynchronizeAspects();
+  }*/
+}
+
+// =======================================================================
+// function : ReplaceAspects
+// purpose  :
+// =======================================================================
+void Vulkan_Group::ReplaceAspects (const Graphic3d_MapOfAspectsToAspects& theMap)
+{
+  if (theMap.IsEmpty())
+  {
+    return;
+  }
+
+  /*Handle(Graphic3d_Aspects) anAspect;
+  if (myAspects != NULL
+   && theMap.Find (myAspects->Aspect(), anAspect))
+  {
+    myAspects->SetAspect (anAspect);
+    if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
+    {
+      aStruct->UpdateStateIfRaytracable (Standard_False);
+    }
+  }
+  for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next)
+  {
+    OpenGl_Aspects* aGlAspect = dynamic_cast<OpenGl_Aspects*> (aNode->elem);
+    if (aGlAspect != NULL
+     && theMap.Find (aGlAspect->Aspect(), anAspect))
+    {
+      aGlAspect->SetAspect (anAspect);
+    }
+  }*/
+}
+
+// =======================================================================
+// function : AddPrimitiveArray
+// purpose  :
+// =======================================================================
+void Vulkan_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
+                                      const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                      const Handle(Graphic3d_Buffer)&      theAttribs,
+                                      const Handle(Graphic3d_BoundBuffer)& theBounds,
+                                      const Standard_Boolean               theToEvalMinMax)
+{
+  if (IsDeleted()
+   || theAttribs.IsNull())
+  {
+    return;
+  }
+
+  Handle(Vulkan_PrimitiveArray) aPrimArray = new Vulkan_PrimitiveArray (theType, theIndices, theAttribs, theBounds);
+  myElements.Append (aPrimArray);
+
+  Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
+}
+
+// =======================================================================
+// function : Text
+// purpose  :
+// =======================================================================
+void Vulkan_Group::Text (const Standard_CString                  theTextUtf,
+                         const Graphic3d_Vertex&                 thePoint,
+                         const Standard_Real                     theHeight,
+                         const Standard_Real                     theAngle,
+                         const Graphic3d_TextPath                theTp,
+                         const Graphic3d_HorizontalTextAlignment theHta,
+                         const Graphic3d_VerticalTextAlignment   theVta,
+                         const Standard_Boolean                  theToEvalMinMax)
+{
+  if (IsDeleted())
+  {
+    return;
+  }
+
+  Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle,
+                         theTp, theHta, theVta, theToEvalMinMax);
+}
+
+// =======================================================================
+// function : Text
+// purpose  :
+// =======================================================================
+void Vulkan_Group::Text (const Standard_CString                  theTextUtf,
+                         const gp_Ax2&                           theOrientation,
+                         const Standard_Real                     theHeight,
+                         const Standard_Real                     theAngle,
+                         const Graphic3d_TextPath                theTp,
+                         const Graphic3d_HorizontalTextAlignment theHTA,
+                         const Graphic3d_VerticalTextAlignment   theVTA,
+                         const Standard_Boolean                  theToEvalMinMax,
+                         const Standard_Boolean                  theHasOwnAnchor)
+{
+  if (IsDeleted())
+  {
+    return;
+  }
+
+  Graphic3d_Group::Text (theTextUtf,
+                         theOrientation,
+                         theHeight,
+                         theAngle,
+                         theTp,
+                         theHTA,
+                         theVTA,
+                         theToEvalMinMax,
+                         theHasOwnAnchor);
+}
+
+// =======================================================================
+// function : SetFlippingOptions
+// purpose  :
+// =======================================================================
+void Vulkan_Group::SetFlippingOptions (const Standard_Boolean ,
+                                       const gp_Ax2& )
+{
+  //
+}
+
+// =======================================================================
+// function : SetStencilTestOptions
+// purpose  :
+// =======================================================================
+void Vulkan_Group::SetStencilTestOptions (const Standard_Boolean )
+{
+  //
+}
+
+// =======================================================================
+// function : AddElement
+// purpose  :
+// =======================================================================
+/*void Vulkan_Group::AddElement (OpenGl_Element* theElem)
+{
+  OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
+
+  aNode->elem = theElem;
+  aNode->next = NULL;
+  (myLast? myLast->next : myFirst) = aNode;
+  myLast = aNode;
+}*/
+
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
+void Vulkan_Group::Render (const Handle(Vulkan_Context)& theCtx) const
+{
+  // Setup aspects
+  /*theWorkspace->SetAllowFaceCulling (myIsClosed
+                                 && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn());
+  const OpenGl_Aspects* aBackAspects = theWorkspace->Aspects();
+  const bool isAspectSet = myAspects != NULL && renderFiltered (theWorkspace, myAspects);*/
+
+  // Render group elements
+  for (Vulkan_ListOfElements::Iterator aNodeIter (myElements); aNodeIter.More(); aNodeIter.Next())
+  {
+    aNodeIter.Value()->Render (theCtx);
+    ///renderFiltered (theWorkspace, aNodeIter->elem);
+  }
+
+  // Restore aspects
+  /*if (isAspectSet)
+    theWorkspace->SetAspects (aBackAspects);*/
+}
+
+// =======================================================================
+// function : Clear
+// purpose  :
+// =======================================================================
+void Vulkan_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
+{
+  if (IsDeleted())
+  {
+    return;
+  }
+
+  myElements.Clear();
+  /*OpenGl_Structure* aStruct = GlStruct();
+  const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
+
+  Release (aCtx);
+  Graphic3d_Group::Clear (theToUpdateStructureMgr);*/
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+/*void Vulkan_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
+{
+  // Delete elements
+  while (myFirst != NULL)
+  {
+    OpenGl_ElementNode* aNext = myFirst->next;
+    OpenGl_Element::Destroy (theGlCtx.get(), myFirst->elem);
+    delete myFirst;
+    myFirst = aNext;
+  }
+  myLast = NULL;
+
+  OpenGl_Element::Destroy (theGlCtx.get(), myAspects);
+}*/
diff --git a/src/Vulkan/Vulkan_Group.hxx b/src/Vulkan/Vulkan_Group.hxx
new file mode 100644 (file)
index 0000000..3722f89
--- /dev/null
@@ -0,0 +1,123 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Group_HeaderFile
+#define _Vulkan_Group_HeaderFile
+
+#include <Graphic3d_Group.hxx>
+
+#include <NCollection_List.hxx>
+
+class Vulkan_PrimitiveArray;
+typedef NCollection_List<Handle(Vulkan_PrimitiveArray)> Vulkan_ListOfElements;
+
+class Vulkan_Context;
+
+//! Implementation of low-level graphic group.
+class Vulkan_Group : public Graphic3d_Group
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Group, Graphic3d_Group)
+public:
+
+  //! Create empty group.
+  //! Will throw exception if not created by OpenGl_Structure.
+  Standard_EXPORT Vulkan_Group (const Handle(Graphic3d_Structure)& theStruct);
+
+  Standard_EXPORT virtual void Clear (const Standard_Boolean theToUpdateStructureMgr) Standard_OVERRIDE;
+
+  //! Return line aspect.
+  virtual Handle(Graphic3d_Aspects) Aspects() const Standard_OVERRIDE
+  {
+    return Handle(Graphic3d_Aspects)();
+    /*return myAspects != NULL
+         ? myAspects->Aspect()
+         : Handle(Graphic3d_Aspects)();*/
+  }
+
+  //! Update aspect.
+  Standard_EXPORT virtual void SetGroupPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect) Standard_OVERRIDE;
+
+  //! Append aspect as an element.
+  Standard_EXPORT virtual void SetPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect) Standard_OVERRIDE;
+
+  //! Update presentation aspects after their modification.
+  Standard_EXPORT virtual void SynchronizeAspects() Standard_OVERRIDE;
+
+  //! Replace aspects specified in the replacement map.
+  Standard_EXPORT virtual void ReplaceAspects (const Graphic3d_MapOfAspectsToAspects& theMap) Standard_OVERRIDE;
+
+  //! Add primitive array element
+  Standard_EXPORT virtual void AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
+                                                  const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                  const Handle(Graphic3d_Buffer)&      theAttribs,
+                                                  const Handle(Graphic3d_BoundBuffer)& theBounds,
+                                                  const Standard_Boolean               theToEvalMinMax) Standard_OVERRIDE;
+
+  //! Add text element
+  Standard_EXPORT virtual void Text (const Standard_CString                  theTextUtf,
+                                     const Graphic3d_Vertex&                 thePoint,
+                                     const Standard_Real                     theHeight,
+                                     const Standard_Real                     theAngle,
+                                     const Graphic3d_TextPath                theTp,
+                                     const Graphic3d_HorizontalTextAlignment theHta,
+                                     const Graphic3d_VerticalTextAlignment   theVta,
+                                     const Standard_Boolean                  theToEvalMinMax) Standard_OVERRIDE;
+
+  //! Add text element in 3D space.
+  Standard_EXPORT virtual void Text (const Standard_CString                  theTextUtf,
+                                     const gp_Ax2&                           theOrientation,
+                                     const Standard_Real                     theHeight,
+                                     const Standard_Real                     theAngle,
+                                     const Graphic3d_TextPath                theTp,
+                                     const Graphic3d_HorizontalTextAlignment theHTA,
+                                     const Graphic3d_VerticalTextAlignment   theVTA,
+                                     const Standard_Boolean                  theToEvalMinMax,
+                                     const Standard_Boolean                  theHasOwnAnchor = Standard_True) Standard_OVERRIDE;
+
+  //! Add flipping element
+  Standard_EXPORT virtual void SetFlippingOptions (const Standard_Boolean theIsEnabled,
+                                                   const gp_Ax2&          theRefPlane) Standard_OVERRIDE;
+
+  //! Add stencil test element
+  Standard_EXPORT virtual void SetStencilTestOptions (const Standard_Boolean theIsEnabled) Standard_OVERRIDE;
+
+public:
+
+  //Vulkan_Structure* VkStruct() const { return (Vulkan_Structure* )(myStructure->CStructure().get()); }
+
+  //Standard_EXPORT void AddElement (OpenGl_Element* theElem);
+
+  Standard_EXPORT virtual void Render (const Handle(Vulkan_Context)& theCtx) const;
+  //Standard_EXPORT virtual void Release (const Handle(OpenGl_Context)&   theGlCtx);
+
+  //! Returns first OpenGL element node of the group.
+  ///const OpenGl_ElementNode* FirstNode() const { return myFirst; }
+
+  //! Returns OpenGL aspect.
+  ///const OpenGl_Aspects* GlAspects() const { return myAspects; }
+
+protected:
+
+  Standard_EXPORT virtual ~Vulkan_Group();
+
+///protected:
+public:
+
+  Vulkan_ListOfElements myElements;
+  //OpenGl_Aspects*     myAspects;
+  //OpenGl_ElementNode* myFirst;
+  //OpenGl_ElementNode* myLast;
+
+};
+
+#endif // _Vulkan_Group_HeaderFile
diff --git a/src/Vulkan/Vulkan_Image.cxx b/src/Vulkan/Vulkan_Image.cxx
new file mode 100644 (file)
index 0000000..8316d1e
--- /dev/null
@@ -0,0 +1,153 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_Image.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_DeviceMemory.hxx>
+#include <Vulkan_DeviceMemoryAllocator.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Image, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_Image
+// purpose  :
+// =======================================================================
+Vulkan_Image::Vulkan_Image()
+: myVkFormat (new VkSurfaceFormatKHR()),
+  myVkImage (NULL)
+{
+  myVkFormat->format = VK_FORMAT_UNDEFINED;
+  myVkFormat->colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
+}
+
+// =======================================================================
+// function : ~Vulkan_Image
+// purpose  :
+// =======================================================================
+Vulkan_Image::~Vulkan_Image()
+{
+  releaseImage();
+}
+
+// =======================================================================
+// function : releaseImage
+// purpose  :
+// =======================================================================
+void Vulkan_Image::releaseImage()
+{
+  if (myVkImageView != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_Image");
+    vkDestroyImageView (myDevice->Device(), myVkImageView, myDevice->HostAllocator());
+    myVkImageView = NULL;
+  }
+  if (myVkImage != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_Image");
+    vkDestroyImage (myDevice->Device(), myVkImage, myDevice->HostAllocator());
+    myVkImage = NULL;
+  }
+  myDepthMemory.Nullify();
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : CreateDepthStencil
+// purpose  :
+// =======================================================================
+bool Vulkan_Image::CreateDepthStencil (const Handle(Vulkan_Device)& theDevice,
+                                       const Graphic3d_Vec2u& theSize)
+{
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL
+   || theSize.x() == 0
+   || theSize.y() == 0)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+  mySize = theSize;
+  myVkFormat->format = VK_FORMAT_D32_SFLOAT_S8_UINT; ///VK_FORMAT_D24_UNORM_S8_UINT;///VK_FORMAT_D24_UNORM_S8_UINT;
+  //myVkFormat->format = VK_FORMAT_D16_UNORM;
+
+  VkImageCreateInfo aDepthInfo = {};
+  aDepthInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+  aDepthInfo.imageType   = VK_IMAGE_TYPE_2D;
+  aDepthInfo.format      = myVkFormat->format;
+  aDepthInfo.extent      = { theSize.x(), theSize.y(), 1 };
+  aDepthInfo.mipLevels   = 1;
+  aDepthInfo.arrayLayers = 1;
+  aDepthInfo.samples     = VK_SAMPLE_COUNT_1_BIT;
+  aDepthInfo.tiling      = VK_IMAGE_TILING_OPTIMAL;
+  aDepthInfo.usage       = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+  aDepthInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+  aDepthInfo.queueFamilyIndexCount = 0;
+  aDepthInfo.pQueueFamilyIndices = NULL;
+  ///aDepthInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; /// TODO why???
+  aDepthInfo.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+  VkResult aRes = vkCreateImage (theDevice->Device(), &aDepthInfo, theDevice->HostAllocator(), &myVkImage);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create depth image", aRes);
+    return false;
+  }
+
+  VkMemoryRequirements aMemReqs = {};
+  vkGetImageMemoryRequirements (theDevice->Device(), myVkImage, &aMemReqs);
+  myDepthMemory = theDevice->DeviceMemoryAllocator()->Allocate (aMemReqs, Vulkan_DeviceMemoryUsage_GpuOnly);
+  if (myDepthMemory.IsNull())
+  {
+    logFailureAndRelease ("failed allocating depth image memory", aRes);
+    return false;
+  }
+
+  const Vulkan_DeviceMemoryInfo aDevMemInfo = myDepthMemory->DeviceMemoryInfo();
+  aRes = vkBindImageMemory (theDevice->Device(), myVkImage, aDevMemInfo.DeviceMemory, aDevMemInfo.Offset);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to bind image memory", aRes);
+    return false;
+  }
+
+  VkImageViewCreateInfo aDepthImgViewInfo = {};
+  aDepthImgViewInfo.sType    = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+  aDepthImgViewInfo.image    = myVkImage;
+  aDepthImgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+  aDepthImgViewInfo.format   = aDepthInfo.format;
+  aDepthImgViewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
+  aDepthImgViewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
+  aDepthImgViewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
+  aDepthImgViewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
+  aDepthImgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
+  aDepthImgViewInfo.subresourceRange.baseMipLevel   = 0;
+  aDepthImgViewInfo.subresourceRange.levelCount     = 1;
+  aDepthImgViewInfo.subresourceRange.baseArrayLayer = 0;
+  aDepthImgViewInfo.subresourceRange.layerCount     = 1;
+
+  aRes = vkCreateImageView (theDevice->Device(), &aDepthImgViewInfo, theDevice->HostAllocator(), &myVkImageView);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create image view", aRes);
+    return false;
+  }
+
+  return true;
+}
diff --git a/src/Vulkan/Vulkan_Image.hxx b/src/Vulkan/Vulkan_Image.hxx
new file mode 100644 (file)
index 0000000..de36e22
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Image_HeaderFile
+#define _Vulkan_Image_HeaderFile
+
+#include <Graphic3d_Vec2.hxx>
+#include <Vulkan_Object.hxx>
+
+#include <memory>
+
+class Vulkan_DeviceMemory;
+
+//! This class defines an Vulkan image.
+class Vulkan_Image : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Image, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_Image();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_Image();
+
+  //! Return image.
+  VkImage Image() const { return myVkImage; }
+
+  //! Return image view.
+  VkImageView ImageView() const { return myVkImageView; }
+
+  //! Return image size.
+  const Graphic3d_Vec2u& Size() const { return mySize; }
+
+  //! Return color surface format.
+  const VkSurfaceFormatKHR& SurfaceFormat() const { return *myVkFormat; }
+
+  //! Create the object, @sa vkCreateImage(), vkCreateImageView().
+  Standard_EXPORT bool CreateDepthStencil (const Handle(Vulkan_Device)& theDevice,
+                                           const Graphic3d_Vec2u& theSize);
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releaseImage(); }
+
+  //! Release the object, @sa vkDestroyImage().
+  Standard_EXPORT void releaseImage();
+
+protected:
+
+  Handle(Vulkan_DeviceMemory) myDepthMemory;
+  std::shared_ptr<VkSurfaceFormatKHR> myVkFormat;
+  VkImage         myVkImage;
+  VkImageView     myVkImageView;
+  Graphic3d_Vec2u mySize;
+
+};
+
+#endif // _Vulkan_Image_HeaderFile
diff --git a/src/Vulkan/Vulkan_Object.cxx b/src/Vulkan/Vulkan_Object.cxx
new file mode 100644 (file)
index 0000000..d63b802
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_Object.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Object, Standard_Transient)
+
+// =======================================================================
+// function : Vulkan_Object
+// purpose  :
+// =======================================================================
+Vulkan_Object::Vulkan_Object()
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_Object
+// purpose  :
+// =======================================================================
+Vulkan_Object::~Vulkan_Object()
+{
+  //
+}
+
+// =======================================================================
+// function : logFailure
+// purpose  :
+// =======================================================================
+void Vulkan_Object::logFailure (const TCollection_AsciiString& theMsg,
+                                int theVkErr,
+                                bool theToRelease)
+{
+  if (theVkErr != VK_SUCCESS)
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString (DynamicType()->Name()) + ", " + theMsg + ": " + Vulkan_Device::FormatVkError (theVkErr));
+  }
+  else
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString (DynamicType()->Name()) + ", " + theMsg);
+  }
+  if (theToRelease)
+  {
+    Release();
+  }
+}
diff --git a/src/Vulkan/Vulkan_Object.hxx b/src/Vulkan/Vulkan_Object.hxx
new file mode 100644 (file)
index 0000000..09375ae
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Object_HeaderFile
+#define _Vulkan_Object_HeaderFile
+
+#include <Vulkan_ForwardDecl.hxx>
+#include <Standard_Type.hxx>
+
+class Vulkan_Device;
+class TCollection_AsciiString;
+
+//! Interface defining a Vulkan object.
+//! After initialization, object holds Vulkan_Device instance, so that it can be automatically released on destruction.
+//! Beware that Vulkan object might hold graphics memory, so that not releasing it at proper time could lead to memory issues.
+class Vulkan_Object : public Standard_Transient
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Object, Standard_Transient)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_Object();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_Object();
+
+  //! Release the object.
+  void Release() { release(); }
+
+  //! Return the Vulkan device.
+  const Handle(Vulkan_Device)& Device() const { return myDevice; }
+
+protected:
+
+  //! Release the object.
+  virtual void release() = 0;
+
+  //! Log failure into messenger and release the object.
+  void logFailureAndRelease (const TCollection_AsciiString& theMsg,
+                             int theVkErr)
+  {
+    logFailure (theMsg, theVkErr, true);
+  }
+
+  //! Log failure into messenger.
+  void logFailure (const TCollection_AsciiString& theMsg,
+                   int theVkErr,
+                   bool theToRelease = false);
+
+  //! @def Vulkan_AssertOnRelease
+  //! Auxiliary macros to check that Vulkan object has been released in proper order.
+#ifdef _DEBUG
+  #define Vulkan_AssertOnRelease(theName) \
+    Standard_ASSERT_RETURN(!myDevice.IsNull(),theName##" destroyed without Vulkan device",); \
+    Standard_ASSERT_RETURN(myDevice->Device()!=NULL,theName##"Vulkan_Buffer destroyed after Vulkan device destruction",);
+#else
+  #define Vulkan_AssertOnRelease
+#endif
+
+protected:
+
+  Handle(Vulkan_Device) myDevice;
+
+};
+
+#endif // _Vulkan_Object_HeaderFile
diff --git a/src/Vulkan/Vulkan_Pipeline.cxx b/src/Vulkan/Vulkan_Pipeline.cxx
new file mode 100644 (file)
index 0000000..b406de6
--- /dev/null
@@ -0,0 +1,340 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_Pipeline.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_PipelineCache.hxx>
+#include <Vulkan_PipelineLayout.hxx>
+#include <Vulkan_RenderPass.hxx>
+#include <Vulkan_Shader.hxx>
+
+#include <vulkan/vulkan.h>
+
+#include <vector>
+
+namespace
+{
+  //! Convert Graphic3d_TypeOfPrimitiveArray enumeration to VkPrimitiveTopology.
+  VkPrimitiveTopology primType2VkTopology (Graphic3d_TypeOfPrimitiveArray thePrimType)
+  {
+    switch (thePrimType)
+    {
+      case Graphic3d_TOPA_POINTS:         return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
+      case Graphic3d_TOPA_SEGMENTS:       return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
+      case Graphic3d_TOPA_POLYLINES:      return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
+      case Graphic3d_TOPA_TRIANGLES:      return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+      case Graphic3d_TOPA_TRIANGLESTRIPS: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+      case Graphic3d_TOPA_TRIANGLEFANS:   return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
+      //
+      case Graphic3d_TOPA_LINES_ADJACENCY:          return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
+      case Graphic3d_TOPA_LINE_STRIP_ADJACENCY:     return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
+      case Graphic3d_TOPA_TRIANGLES_ADJACENCY:      return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
+      case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
+      //
+      case Graphic3d_TOPA_QUADRANGLES:
+      case Graphic3d_TOPA_QUADRANGLESTRIPS:
+      case Graphic3d_TOPA_POLYGONS:
+      case Graphic3d_TOPA_UNDEFINED:
+        return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
+    }
+    return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
+  }
+
+  static VkFormat vertAttrib2VkFormat (Graphic3d_TypeOfData theType)
+  {
+    switch (theType)
+    {
+      case Graphic3d_TOD_USHORT: return VK_FORMAT_R16_UINT;
+      case Graphic3d_TOD_UINT:   return VK_FORMAT_R32_UINT;
+      case Graphic3d_TOD_VEC2:   return VK_FORMAT_R32G32_SFLOAT;
+      case Graphic3d_TOD_VEC3:   return VK_FORMAT_R32G32B32_SFLOAT;
+      case Graphic3d_TOD_VEC4:   return VK_FORMAT_R32G32B32A32_SFLOAT;
+      case Graphic3d_TOD_VEC4UB: return VK_FORMAT_B8G8R8A8_UNORM;
+      case Graphic3d_TOD_FLOAT:  return VK_FORMAT_R32_SFLOAT;
+    }
+    return VK_FORMAT_UNDEFINED;
+  }
+}
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Pipeline, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_Pipeline
+// purpose  :
+// =======================================================================
+Vulkan_Pipeline::Vulkan_Pipeline()
+: myVkPipeline (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_Pipeline
+// purpose  :
+// =======================================================================
+Vulkan_Pipeline::~Vulkan_Pipeline()
+{
+  releasePipeline();
+}
+
+// =======================================================================
+// function : releasePipeline
+// purpose  :
+// =======================================================================
+void Vulkan_Pipeline::releasePipeline()
+{
+  if (myVkPipeline != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_Pipeline");
+    vkDestroyPipeline (myDevice->Device(), myVkPipeline, myDevice->HostAllocator());
+    myVkPipeline = NULL;
+  }
+  myPipelineLayout.Nullify();
+  myPipelineCache.Nullify();
+  myShaderVert.Nullify();
+  myShaderFrag.Nullify();
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_Pipeline::Create (const Handle(Vulkan_Device)& theDevice,
+                              const Handle(Vulkan_RenderPass)& theRenderPass,
+                              const Handle(Vulkan_PipelineLayout)& theLayout,
+                              const Handle(Vulkan_Shader)& theShaderVert,
+                              const Handle(Vulkan_Shader)& theShaderFrag,
+                              const Graphic3d_Vec2u& theViewport,
+                              const Vulkun_PipelineCfg& theCfg)
+{
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL
+   || theShaderVert.IsNull()
+   || theShaderVert->Shader() == NULL
+   || theShaderFrag.IsNull()
+   || theShaderFrag->Shader() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+  myShaderVert = theShaderVert;
+  myShaderFrag = theShaderFrag;
+  myPipelineLayout = theLayout;
+  myCfg = theCfg;
+  /*if (myPipelineLayout.IsNull())
+  {
+    myPipelineLayout = new Vulkan_PipelineLayout();
+    if (!myPipelineLayout->Create (theDevice, NULL))
+    {
+      return false;
+    }
+  }*/
+  if (myPipelineCache.IsNull())
+  {
+    myPipelineCache = new Vulkan_PipelineCache();
+    if (!myPipelineCache->Create (theDevice))
+    {
+      Release();
+      return false;
+    }
+  }
+
+  VkPipelineShaderStageCreateInfo aShaderStages[2] = {};
+  {
+    VkPipelineShaderStageCreateInfo& aVertStage = aShaderStages[0];
+    aVertStage.sType   = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+    aVertStage.pNext   = NULL;
+    aVertStage.flags   = 0;
+    aVertStage.stage   = VK_SHADER_STAGE_VERTEX_BIT;
+    aVertStage.module  =  theShaderVert->Shader();
+    aVertStage.pName   = "main";
+    aVertStage.pSpecializationInfo = NULL;
+  }
+  {
+    VkPipelineShaderStageCreateInfo& aFragStage = aShaderStages[1];
+    aFragStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+    aFragStage.pNext = NULL;
+    aFragStage.flags = 0;
+    aFragStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
+    aFragStage.module = theShaderFrag->Shader();
+    aFragStage.pName = "main";
+    aFragStage.pSpecializationInfo = NULL;
+  }
+
+  VkVertexInputBindingDescription aVertexInputBinding;
+  aVertexInputBinding.binding   = 0;
+  aVertexInputBinding.stride    = myCfg.Stride;
+  aVertexInputBinding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
+
+  std::vector<VkVertexInputAttributeDescription> aVertexInputAttributes (myCfg.NbAttributes);
+  for (Standard_Integer anAttribIter = 0; anAttribIter < myCfg.NbAttributes; ++anAttribIter)
+  {
+    const Vulkun_VertexAttribute& anAttrib = myCfg.Attributes[anAttribIter];
+    VkVertexInputAttributeDescription& anInAttrib = aVertexInputAttributes[anAttribIter];
+    anInAttrib.location = anAttrib.Location;
+    anInAttrib.binding = 0;
+    anInAttrib.format = vertAttrib2VkFormat (anAttrib.DataType);
+    anInAttrib.offset = anAttrib.Offset;
+  }
+
+  VkPipelineVertexInputStateCreateInfo aVertexInput;
+  aVertexInput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+  aVertexInput.pNext = NULL;
+  aVertexInput.flags = 0;
+  aVertexInput.vertexBindingDescriptionCount   = 1;
+  aVertexInput.pVertexBindingDescriptions      = &aVertexInputBinding;
+  aVertexInput.vertexAttributeDescriptionCount = (uint32_t )aVertexInputAttributes.size();
+  aVertexInput.pVertexAttributeDescriptions    = aVertexInputAttributes.data();
+
+  VkPipelineInputAssemblyStateCreateInfo anInputAssembly;
+  anInputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+  anInputAssembly.pNext = NULL;
+  anInputAssembly.flags = 0;
+  anInputAssembly.topology = primType2VkTopology (myCfg.PrimType);
+  anInputAssembly.primitiveRestartEnable = VK_FALSE;
+
+  VkViewport aViewport = {};
+  aViewport.x = 0.0f;
+  aViewport.y = (float )theViewport.y();
+  aViewport.width  =  (float )theViewport.x();
+  aViewport.height = -(float )theViewport.y();
+  aViewport.minDepth = 0.0f;
+  aViewport.maxDepth = 1.0f;
+  VkRect2D aScissor = {};
+  aScissor.offset.x = 0;
+  aScissor.offset.y = 0;
+  aScissor.extent.width  = theViewport.x();
+  aScissor.extent.height = theViewport.y();
+
+  VkPipelineViewportStateCreateInfo aViewportInfo;
+  aViewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+  aViewportInfo.pNext = NULL;
+  aViewportInfo.flags = 0;
+  aViewportInfo.viewportCount = 1;
+  aViewportInfo.pViewports = &aViewport;
+  aViewportInfo.scissorCount = 1;
+  aViewportInfo.pScissors = &aScissor;
+
+  VkPipelineRasterizationStateCreateInfo aRaster;
+  aRaster.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+  aRaster.pNext = NULL;
+  aRaster.flags = 0;
+  aRaster.depthClampEnable = VK_FALSE;
+  aRaster.rasterizerDiscardEnable = VK_FALSE;
+  aRaster.polygonMode = VK_POLYGON_MODE_FILL;
+  aRaster.cullMode = VK_CULL_MODE_BACK_BIT; ///VK_CULL_MODE_NONE;
+  aRaster.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
+  ///aRaster.frontFace = VK_FRONT_FACE_CLOCKWISE;
+  aRaster.depthBiasEnable = VK_FALSE;
+  aRaster.depthBiasConstantFactor = 0.0f;
+  aRaster.depthBiasClamp = 0.0f;
+  aRaster.depthBiasSlopeFactor = 0.0f;
+  aRaster.lineWidth = 1.0f;
+
+  VkPipelineMultisampleStateCreateInfo aMultisample;
+  aMultisample.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+  aMultisample.pNext = NULL;
+  aMultisample.flags = 0;
+  aMultisample.rasterizationSamples = VkSampleCountFlagBits::VK_SAMPLE_COUNT_1_BIT;
+  aMultisample.sampleShadingEnable = VK_FALSE;
+  aMultisample.minSampleShading = 0;
+  aMultisample.pSampleMask = NULL;
+  aMultisample.alphaToCoverageEnable = VK_FALSE;
+  aMultisample.alphaToOneEnable = VK_FALSE;
+
+  VkStencilOpState aNoOpStencil = {};
+  aNoOpStencil.failOp      = VK_STENCIL_OP_KEEP;
+  aNoOpStencil.passOp      = VK_STENCIL_OP_KEEP;
+  aNoOpStencil.depthFailOp = VK_STENCIL_OP_KEEP;
+  aNoOpStencil.compareOp   = VK_COMPARE_OP_ALWAYS;
+  aNoOpStencil.compareMask = 0;
+  aNoOpStencil.writeMask   = 0;
+  aNoOpStencil.reference   = 0;
+
+  VkPipelineDepthStencilStateCreateInfo aDepthStencil;
+  aDepthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+  aDepthStencil.pNext = NULL;
+  aDepthStencil.flags = 0;
+  aDepthStencil.depthTestEnable  = VK_TRUE;
+  aDepthStencil.depthWriteEnable = VK_TRUE;
+  aDepthStencil.depthCompareOp   = VK_COMPARE_OP_LESS_OR_EQUAL;
+  aDepthStencil.depthBoundsTestEnable = VK_FALSE;
+  aDepthStencil.stencilTestEnable = VK_FALSE;
+  aDepthStencil.front = aNoOpStencil;
+  aDepthStencil.back  = aNoOpStencil;
+  aDepthStencil.minDepthBounds = 0.0f;
+  aDepthStencil.maxDepthBounds = 0.0f;
+
+  VkPipelineColorBlendAttachmentState aBlendAttachments;
+  aBlendAttachments.blendEnable         = VK_FALSE;
+  aBlendAttachments.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
+  aBlendAttachments.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
+  aBlendAttachments.colorBlendOp        = VK_BLEND_OP_ADD;
+  aBlendAttachments.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
+  aBlendAttachments.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
+  aBlendAttachments.alphaBlendOp        = VK_BLEND_OP_ADD;
+  aBlendAttachments.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT;
+
+  VkPipelineColorBlendStateCreateInfo aBlending;
+  aBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+  aBlending.pNext = NULL;
+  aBlending.flags = 0;
+  aBlending.logicOpEnable = VK_FALSE;
+  aBlending.logicOp = VK_LOGIC_OP_CLEAR;
+  aBlending.attachmentCount = 1;
+  aBlending.pAttachments = &aBlendAttachments;
+  aBlending.blendConstants;
+  aBlending.blendConstants[0] = 1.0f;
+  aBlending.blendConstants[1] = 1.0f;
+  aBlending.blendConstants[2] = 1.0f;
+  aBlending.blendConstants[3] = 1.0f;
+
+  VkGraphicsPipelineCreateInfo aPipeInfo;
+  aPipeInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+  aPipeInfo.pNext = NULL;
+  aPipeInfo.flags = 0;
+  aPipeInfo.stageCount = 2;
+  aPipeInfo.pStages    = aShaderStages;
+  aPipeInfo.pVertexInputState   = &aVertexInput;
+  aPipeInfo.pInputAssemblyState = &anInputAssembly;
+  aPipeInfo.pTessellationState  = VK_NULL_HANDLE;
+  aPipeInfo.pViewportState      = &aViewportInfo;
+  aPipeInfo.pRasterizationState = &aRaster;
+  aPipeInfo.pMultisampleState   = &aMultisample;
+  aPipeInfo.pDepthStencilState  = &aDepthStencil;
+  aPipeInfo.pColorBlendState    = &aBlending;
+  aPipeInfo.pDynamicState       = NULL;
+  aPipeInfo.layout     = myPipelineLayout->PipelineLayout();
+  aPipeInfo.renderPass = theRenderPass->RenderPass();
+  aPipeInfo.subpass    = 0;
+  aPipeInfo.basePipelineIndex = 0;
+  aPipeInfo.basePipelineHandle = VK_NULL_HANDLE;
+
+  VkResult aRes = vkCreateGraphicsPipelines (theDevice->Device(),
+                                             !myPipelineCache.IsNull() ? myPipelineCache->PipelineCache() : NULL,
+                                             1, &aPipeInfo,
+                                             theDevice->HostAllocator(), &myVkPipeline);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create pipeline", aRes);
+    return false;
+  }
+
+  return true;
+}
diff --git a/src/Vulkan/Vulkan_Pipeline.hxx b/src/Vulkan/Vulkan_Pipeline.hxx
new file mode 100644 (file)
index 0000000..2169a8f
--- /dev/null
@@ -0,0 +1,165 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Pipeline_HeaderFile
+#define _Vulkan_Pipeline_HeaderFile
+
+#include <Graphic3d_TypeOfPrimitiveArray.hxx>
+#include <Graphic3d_TypeOfShadingModel.hxx>
+#include <Graphic3d_Vec2.hxx>
+#include <Graphic3d_Buffer.hxx>
+#include <Vulkan_Object.hxx>
+
+class Vulkan_PipelineCache;
+class Vulkan_PipelineLayout;
+class Vulkan_RenderPass;
+class Vulkan_Shader;
+
+//! Close to Graphic3d_Attribute
+struct Vulkun_VertexAttribute
+{
+  Graphic3d_TypeOfAttribute Location; //!< attribute identifier in vertex shader, 0 is reserved for vertex position
+  Graphic3d_TypeOfData      DataType; //!< vec2,vec3,vec4,vec4ub
+  uint32_t                  Offset;   //!< byte offset to the data within vertex buffer
+
+  Vulkun_VertexAttribute() : Location (Graphic3d_TOA_POS), DataType (Graphic3d_TOD_VEC3), Offset (0) {}
+
+  //! Matching two instances.
+  bool IsEqual (const Vulkun_VertexAttribute& theOther) const
+  {
+    return Location == theOther.Location
+        && DataType == theOther.DataType
+        && Offset   == theOther.Offset;
+  }
+};
+
+struct Vulkun_PipelineCfg
+{
+  Graphic3d_TypeOfPrimitiveArray PrimType;
+  Graphic3d_TypeOfShadingModel   ShadingModel;
+  Vulkun_VertexAttribute         Attributes[5];
+  Standard_Integer               NbAttributes;
+  uint32_t                       Stride;
+
+  Vulkun_PipelineCfg() : PrimType (Graphic3d_TOPA_UNDEFINED), ShadingModel (Graphic3d_TOSM_UNLIT), NbAttributes (0), Stride (0) {}
+
+public:
+  static const Standard_Integer THE_MAX_NB_ATTRIBUTES = 5;
+
+  //! Hash value, for Map interface.
+  static Standard_Integer HashCode (const Vulkun_PipelineCfg& theCfg,
+                                    const Standard_Integer theUpper)
+  {
+    uint32_t aHashCode = 0;
+    aHashCode = aHashCode ^ ::HashCode (theCfg.PrimType,     theUpper);
+    aHashCode = aHashCode ^ ::HashCode (theCfg.NbAttributes, theUpper);
+    aHashCode = aHashCode ^ ::HashCode (theCfg.ShadingModel, theUpper);
+    return ::HashCode (Standard_Integer(aHashCode), theUpper);
+  }
+
+  //! Matching two instances, for Map interface.
+  bool IsEqual (const Vulkun_PipelineCfg& theOther) const
+  {
+    if (PrimType != theOther.PrimType
+     || NbAttributes != theOther.NbAttributes
+     || Stride != theOther.Stride)
+    {
+      return false;
+    }
+    for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
+    {
+      if (!Attributes[anAttribIter].IsEqual (theOther.Attributes[anAttribIter]))
+      {
+        return false;
+      }
+    }
+    return true;
+  }
+};
+
+//! This class defines an Vulkan Pipeline.
+class Vulkan_Pipeline : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Pipeline, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_Pipeline();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_Pipeline();
+
+  //! Return object.
+  VkPipeline Pipeline() const { return myVkPipeline; }
+
+  //! Return pipeline layout.
+  const Handle(Vulkan_PipelineLayout)& PipelineLayout() const { return myPipelineLayout; }
+
+  //! Create the object, @sa vkCreateGraphicsPipelines().
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice,
+                               const Handle(Vulkan_RenderPass)& theRenderPass,
+                               const Handle(Vulkan_PipelineLayout)& theLayout,
+                               const Handle(Vulkan_Shader)& theShaderVert,
+                               const Handle(Vulkan_Shader)& theShaderFrag,
+                               const Graphic3d_Vec2u& theViewport,
+                               const Vulkun_PipelineCfg& theCfg);
+
+  //! Return primitive array type.
+  const Vulkun_PipelineCfg& Configuration() const { return myCfg; }
+
+  //! Equality check.
+  bool IsEqual (const Handle(Vulkan_Pipeline)& theOther) const
+  {
+    return !theOther.IsNull()
+         && (theOther == this
+          || myCfg.IsEqual (theOther->myCfg));
+  }
+
+public:
+
+  //! Hash value, for Map interface.
+  static Standard_Integer HashCode (const Handle(Vulkan_Pipeline)& thePipeline,
+                                    const Standard_Integer theUpper)
+  {
+    return !thePipeline.IsNull()
+          ? Vulkun_PipelineCfg::HashCode (thePipeline->myCfg, theUpper)
+          : 1;
+  }
+
+  //! Matching two instances, for Map interface.
+  static bool IsEqual (const Handle(Vulkan_Pipeline)& thePipeline1,
+                       const Handle(Vulkan_Pipeline)& thePipeline2)
+  {
+    return thePipeline1->IsEqual (thePipeline2);
+  }
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releasePipeline(); }
+
+  //! Release the object, @sa vkDestroyPipeline().
+  Standard_EXPORT void releasePipeline();
+
+protected:
+
+  Handle(Vulkan_Shader) myShaderVert;
+  Handle(Vulkan_Shader) myShaderFrag;
+  Handle(Vulkan_PipelineCache)  myPipelineCache;
+  Handle(Vulkan_PipelineLayout) myPipelineLayout;
+  VkPipeline myVkPipeline;
+  Vulkun_PipelineCfg myCfg;
+
+};
+
+#endif // _Vulkan_Pipeline_HeaderFile
diff --git a/src/Vulkan/Vulkan_PipelineCache.cxx b/src/Vulkan/Vulkan_PipelineCache.cxx
new file mode 100644 (file)
index 0000000..524ce40
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_PipelineCache.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_PipelineCache, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_PipelineCache
+// purpose  :
+// =======================================================================
+Vulkan_PipelineCache::Vulkan_PipelineCache()
+: myVkPipelineCache (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_PipelineCache
+// purpose  :
+// =======================================================================
+Vulkan_PipelineCache::~Vulkan_PipelineCache()
+{
+  releasePipelineCache();
+}
+
+// =======================================================================
+// function : releasePipelineCache
+// purpose  :
+// =======================================================================
+void Vulkan_PipelineCache::releasePipelineCache()
+{
+  if (myVkPipelineCache != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_PipelineCache");
+    vkDestroyPipelineCache (myDevice->Device(), myVkPipelineCache, myDevice->HostAllocator());
+    myVkPipelineCache = NULL;
+  }
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_PipelineCache::Create (const Handle(Vulkan_Device)& theDevice)
+{
+  if (myVkPipelineCache != NULL
+   && myDevice == theDevice)
+  {
+    return true;
+  }
+
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+
+  VkPipelineCacheCreateInfo aVkPipelineCacheInfo;
+  aVkPipelineCacheInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
+  aVkPipelineCacheInfo.pNext = NULL;
+  aVkPipelineCacheInfo.flags = 0;
+  aVkPipelineCacheInfo.initialDataSize = 0;
+  aVkPipelineCacheInfo.pInitialData = NULL;
+
+  VkResult aRes = vkCreatePipelineCache (theDevice->Device(), &aVkPipelineCacheInfo, theDevice->HostAllocator(), &myVkPipelineCache);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create pipeline cache", aRes);
+    return false;
+  }
+  return true;
+}
diff --git a/src/Vulkan/Vulkan_PipelineCache.hxx b/src/Vulkan/Vulkan_PipelineCache.hxx
new file mode 100644 (file)
index 0000000..8e7523e
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_PipelineCache_HeaderFile
+#define _Vulkan_PipelineCache_HeaderFile
+
+#include <Vulkan_Object.hxx>
+
+//! This class defines an Vulkan Pipeline Cache.
+class Vulkan_PipelineCache : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_PipelineCache, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_PipelineCache();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_PipelineCache();
+
+  //! Return object.
+  VkPipelineCache PipelineCache() const { return myVkPipelineCache; }
+
+  //! Create the object, @sa vkCreatePipelineCache().
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice);
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releasePipelineCache(); }
+
+  //! Release the object, @sa vkDestroyPipelineCache().
+  Standard_EXPORT void releasePipelineCache();
+
+protected:
+
+  VkPipelineCache myVkPipelineCache;
+
+};
+
+#endif // _Vulkan_PipelineCache_HeaderFile
diff --git a/src/Vulkan/Vulkan_PipelineLayout.cxx b/src/Vulkan/Vulkan_PipelineLayout.cxx
new file mode 100644 (file)
index 0000000..9000ef5
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_PipelineLayout.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_DescriptorSetLayout.hxx>
+#include <Vulkan_Device.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_PipelineLayout, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_PipelineLayout
+// purpose  :
+// =======================================================================
+Vulkan_PipelineLayout::Vulkan_PipelineLayout()
+: myVkPipelineLayout (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_PipelineLayout
+// purpose  :
+// =======================================================================
+Vulkan_PipelineLayout::~Vulkan_PipelineLayout()
+{
+  releasePipelineLayout();
+}
+
+// =======================================================================
+// function : releasePipelineLayout
+// purpose  :
+// =======================================================================
+void Vulkan_PipelineLayout::releasePipelineLayout()
+{
+  if (myVkPipelineLayout != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_PipelineLayout");
+    vkDestroyPipelineLayout (myDevice->Device(), myVkPipelineLayout, myDevice->HostAllocator());
+    myVkPipelineLayout = NULL;
+  }
+  myDescSetLayout.Nullify();
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_PipelineLayout::Create (const Handle(Vulkan_Device)& theDevice,
+                                    const Handle(Vulkan_DescriptorSetLayout)& theDescSetLayout)
+{
+  if (myVkPipelineLayout != NULL
+   && myDevice == theDevice
+   && myDescSetLayout == theDescSetLayout)
+  {
+    return true;
+  }
+
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+  myDescSetLayout = theDescSetLayout;
+
+  VkPipelineLayoutCreateInfo aVkPipelineLayoutInfo;
+  aVkPipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+  aVkPipelineLayoutInfo.pNext = NULL;
+  aVkPipelineLayoutInfo.flags = 0;
+  aVkPipelineLayoutInfo.setLayoutCount = 1;
+  aVkPipelineLayoutInfo.pSetLayouts = &theDescSetLayout->DescriptorSetLayout();
+  aVkPipelineLayoutInfo.pushConstantRangeCount = 0;
+  aVkPipelineLayoutInfo.pPushConstantRanges = NULL;
+
+  VkResult aRes = vkCreatePipelineLayout (theDevice->Device(), &aVkPipelineLayoutInfo, theDevice->HostAllocator(), &myVkPipelineLayout);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create pipeline layout", aRes);
+    return false;
+  }
+
+  return true;
+}
diff --git a/src/Vulkan/Vulkan_PipelineLayout.hxx b/src/Vulkan/Vulkan_PipelineLayout.hxx
new file mode 100644 (file)
index 0000000..9fa712a
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_PipelineLayout_HeaderFile
+#define _Vulkan_PipelineLayout_HeaderFile
+
+#include <Vulkan_Object.hxx>
+
+class Vulkan_DescriptorSetLayout;
+
+//! This class defines an Vulkan Pipeline Layout.
+class Vulkan_PipelineLayout : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_PipelineLayout, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_PipelineLayout();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_PipelineLayout();
+
+  //! Return object.
+  VkPipelineLayout PipelineLayout() const { return myVkPipelineLayout; }
+
+  //! Create the object, @sa vkCreatePipelineLayout().
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice,
+                               const Handle(Vulkan_DescriptorSetLayout)& theDescSetLayout);
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releasePipelineLayout(); }
+
+  //! Release the object, @sa vkDestroyPipelineLayout().
+  Standard_EXPORT void releasePipelineLayout();
+
+protected:
+
+  Handle(Vulkan_DescriptorSetLayout) myDescSetLayout;
+  VkPipelineLayout myVkPipelineLayout;
+
+};
+
+#endif // _Vulkan_PipelineLayout_HeaderFile
diff --git a/src/Vulkan/Vulkan_PrimitiveArray.cxx b/src/Vulkan/Vulkan_PrimitiveArray.cxx
new file mode 100644 (file)
index 0000000..f0a129f
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_PrimitiveArray.hxx>
+
+#include <Graphic3d_ArrayOfPrimitives.hxx>
+#include <Graphic3d_GroupDefinitionError.hxx>
+#include <Graphic3d_Structure.hxx>
+#include <Vulkan_Buffer.hxx>
+#include <Vulkan_CommandBuffer.hxx>
+#include <Vulkan_Context.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_PrimitiveArray, Standard_Transient)
+
+// =======================================================================
+// function : Vulkan_PrimitiveArray
+// purpose  :
+// =======================================================================
+Vulkan_PrimitiveArray::Vulkan_PrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
+                                              const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                              const Handle(Graphic3d_Buffer)&      theAttribs,
+                                              const Handle(Graphic3d_BoundBuffer)& theBounds)
+: myIndices (theIndices),
+  myAttribs (theAttribs),
+  myBounds (theBounds),
+  myType (theType)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_PrimitiveArray
+// purpose  :
+// =======================================================================
+Vulkan_PrimitiveArray::~Vulkan_PrimitiveArray()
+{
+  Release();
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void Vulkan_PrimitiveArray::Release()
+{
+  myVboAttribs.Nullify();
+  myVboIndices.Nullify();
+}
+
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
+void Vulkan_PrimitiveArray::Render (const Handle(Vulkan_Context)& theCtx)
+{
+  if (myVboAttribs.IsNull()
+  && !myAttribs.IsNull())
+  {
+    myVboAttribs = new Vulkan_Buffer();
+    myVboAttribs->init (theCtx->Device(), myAttribs->Data(), myAttribs->Size(), Vulkan_BufferType_Vertex);
+  }
+  if (myVboIndices.IsNull()
+  && !myIndices.IsNull())
+  {
+    myVboIndices = new Vulkan_Buffer();
+    myVboIndices->init (theCtx->Device(), myIndices->Data(), myIndices->Size(), Vulkan_BufferType_Index);
+  }
+
+  if (myVboAttribs.IsNull())
+  {
+    return;
+  }
+
+  Vulkun_PipelineCfg aCfg;
+  aCfg.PrimType = myType;
+  aCfg.NbAttributes = Min (myAttribs->NbAttributes, Vulkun_PipelineCfg::THE_MAX_NB_ATTRIBUTES);
+  aCfg.Stride = myAttribs->IsInterleaved() ? myAttribs->Stride : 0;
+  aCfg.ShadingModel = Graphic3d_TOSM_UNLIT;
+  if (int(aCfg.PrimType) >= int(Graphic3d_TOPA_TRIANGLES))
+  {
+    aCfg.ShadingModel = aCfg.NbAttributes > 1 ? Graphic3d_TOSM_FRAGMENT : Graphic3d_TOSM_FACET;
+  }
+  uint32_t anOffset = 0;
+  for (Standard_Integer anAttribIter = 0; anAttribIter < aCfg.NbAttributes; ++anAttribIter)
+  {
+    const Graphic3d_Attribute& anAttribSrc = myAttribs->Attribute (anAttribIter);
+    Vulkun_VertexAttribute& anAttribDst = aCfg.Attributes[anAttribIter];
+    anAttribDst.Location = anAttribSrc.Id;
+    anAttribDst.DataType = anAttribSrc.DataType;
+    anAttribDst.Offset   = anOffset;
+
+    if (myAttribs->IsInterleaved())
+    {
+      anOffset += anAttribSrc.Stride();
+    }
+  }
+
+  VkBuffer aVkVertBuffers[1] = { myVboAttribs->Buffer() };
+  VkDeviceSize aVkVertOffsets[1] = {0};
+  const VkCommandBuffer& aVkCmdBuffer = theCtx->CommandBuffer()->CommandBuffer();
+  theCtx->ActivatePipeline (aCfg);
+  vkCmdBindVertexBuffers (aVkCmdBuffer, 0, 1, aVkVertBuffers, aVkVertOffsets);
+  if (!myVboIndices.IsNull())
+  {
+    vkCmdBindIndexBuffer (aVkCmdBuffer, myVboIndices->Buffer(), 0, myIndices->Stride == 4 ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16);
+    vkCmdDrawIndexed (aVkCmdBuffer, myIndices->NbElements, 1, 0, 0, 0);
+  }
+  else
+  {
+    vkCmdDraw (aVkCmdBuffer, myAttribs->NbElements, 1, 0, 0);
+  }
+}
diff --git a/src/Vulkan/Vulkan_PrimitiveArray.hxx b/src/Vulkan/Vulkan_PrimitiveArray.hxx
new file mode 100644 (file)
index 0000000..a90d4f4
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_PrimitiveArray_HeaderFile
+#define _Vulkan_PrimitiveArray_HeaderFile
+
+#include <Graphic3d_TypeOfPrimitiveArray.hxx>
+#include <Standard_Type.hxx>
+
+class Graphic3d_Buffer;
+class Graphic3d_BoundBuffer;
+class Graphic3d_IndexBuffer;
+class Vulkan_Context;
+class Vulkan_Buffer;
+
+class Vulkan_PrimitiveArray : public Standard_Transient
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_PrimitiveArray, Standard_Transient)
+public:
+
+  Standard_EXPORT Vulkan_PrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
+                                         const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                         const Handle(Graphic3d_Buffer)&      theAttribs,
+                                         const Handle(Graphic3d_BoundBuffer)& theBounds);
+
+  Standard_EXPORT virtual ~Vulkan_PrimitiveArray();
+
+  Standard_EXPORT virtual void Release();
+
+  Standard_EXPORT virtual void Render (const Handle(Vulkan_Context)& theCtx);
+
+protected:
+
+  Handle(Graphic3d_IndexBuffer) myIndices;
+  Handle(Graphic3d_Buffer)      myAttribs;
+  Handle(Graphic3d_BoundBuffer) myBounds;
+
+  Handle(Vulkan_Buffer) myVboAttribs;
+  Handle(Vulkan_Buffer) myVboIndices;
+  Graphic3d_TypeOfPrimitiveArray myType;
+
+};
+
+#endif // _Vulkan_PrimitiveArray_HeaderFile
diff --git a/src/Vulkan/Vulkan_RenderPass.cxx b/src/Vulkan/Vulkan_RenderPass.cxx
new file mode 100644 (file)
index 0000000..fec19cc
--- /dev/null
@@ -0,0 +1,142 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_RenderPass.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_Image.hxx>
+#include <Vulkan_Surface.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_RenderPass, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_RenderPass
+// purpose  :
+// =======================================================================
+Vulkan_RenderPass::Vulkan_RenderPass()
+: myVkRenderPass (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_RenderPass
+// purpose  :
+// =======================================================================
+Vulkan_RenderPass::~Vulkan_RenderPass()
+{
+  releaseRenderPass();
+}
+
+// =======================================================================
+// function : releaseRenderPass
+// purpose  :
+// =======================================================================
+void Vulkan_RenderPass::releaseRenderPass()
+{
+  if (myVkRenderPass != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_RenderPass");
+    vkDestroyRenderPass (myDevice->Device(), myVkRenderPass, myDevice->HostAllocator());
+    myVkRenderPass = NULL;
+  }
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_RenderPass::Create (const Handle(Vulkan_Device)& theDevice,
+                                const Handle(Vulkan_Surface)& theSurface)
+{
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+
+  VkAttachmentDescription aVkAttachments[2] = {};
+  {
+    VkAttachmentDescription& aColorAttach = aVkAttachments[0];
+    aColorAttach.flags          = 0;
+    aColorAttach.format         = !theSurface.IsNull() ? theSurface->ColorFormat().format : VK_FORMAT_UNDEFINED;
+    aColorAttach.samples        = VK_SAMPLE_COUNT_1_BIT;
+    aColorAttach.loadOp         = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    aColorAttach.storeOp        = VK_ATTACHMENT_STORE_OP_STORE;
+    aColorAttach.stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+    aColorAttach.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+    aColorAttach.initialLayout  = VK_IMAGE_LAYOUT_UNDEFINED;
+    aColorAttach.finalLayout    = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+  }
+  if (!theSurface->DepthImage().IsNull())
+  {
+    VkAttachmentDescription& aDepthAttach = aVkAttachments[1];
+    aDepthAttach.flags          = 0;
+    aDepthAttach.format         = theSurface->DepthImage()->SurfaceFormat().format;
+    aDepthAttach.samples        = VK_SAMPLE_COUNT_1_BIT;
+    aDepthAttach.loadOp         = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    aDepthAttach.storeOp        = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+    aDepthAttach.stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+    aDepthAttach.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+    aDepthAttach.initialLayout  = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    aDepthAttach.finalLayout    = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+  }
+
+  VkAttachmentReference aColorAttachRef = {};
+  aColorAttachRef.attachment = 0;
+  aColorAttachRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+  VkAttachmentReference aDepthAttachRef = {};
+  aDepthAttachRef.attachment = 1;
+  aDepthAttachRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+  VkSubpassDescription aVkSubpassDesc;
+  aVkSubpassDesc.flags = 0;
+  aVkSubpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+  aVkSubpassDesc.inputAttachmentCount = 0;
+  aVkSubpassDesc.pInputAttachments = NULL;
+  aVkSubpassDesc.colorAttachmentCount = 1;
+  aVkSubpassDesc.pColorAttachments = &aColorAttachRef;
+  aVkSubpassDesc.pResolveAttachments = NULL;
+  aVkSubpassDesc.pDepthStencilAttachment = &aDepthAttachRef;
+  aVkSubpassDesc.preserveAttachmentCount = 0;
+  aVkSubpassDesc.pPreserveAttachments = NULL;
+
+  VkRenderPassCreateInfo aVkRenderPassInfo;
+  aVkRenderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+  aVkRenderPassInfo.pNext = NULL;
+  aVkRenderPassInfo.flags = 0;
+  aVkRenderPassInfo.attachmentCount = !theSurface->DepthImage().IsNull() ? 2 : 1;
+  aVkRenderPassInfo.pAttachments = aVkAttachments;
+  aVkRenderPassInfo.subpassCount = 1;
+  aVkRenderPassInfo.pSubpasses = &aVkSubpassDesc;
+  aVkRenderPassInfo.dependencyCount = 0;
+  aVkRenderPassInfo.pDependencies = NULL;
+
+  VkResult aRes = vkCreateRenderPass (theDevice->Device(), &aVkRenderPassInfo, theDevice->HostAllocator(), &myVkRenderPass);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create render pass", aRes);
+    return false;
+  }
+
+  return true;
+}
diff --git a/src/Vulkan/Vulkan_RenderPass.hxx b/src/Vulkan/Vulkan_RenderPass.hxx
new file mode 100644 (file)
index 0000000..607fd45
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_RenderPass_HeaderFile
+#define _Vulkan_RenderPass_HeaderFile
+
+#include <Vulkan_Object.hxx>
+
+class Vulkan_Surface;
+
+//! This class defines an Vulkan Render Pass.
+class Vulkan_RenderPass : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_RenderPass, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_RenderPass();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_RenderPass();
+
+  //! Return object.
+  VkRenderPass RenderPass() const { return myVkRenderPass; }
+
+  //! Create the object, @sa vkCreatePipelineCache().
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice,
+                               const Handle(Vulkan_Surface)& theSurface);
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releaseRenderPass(); }
+
+  //! Release the object, @sa vkDestroyRenderPass().
+  Standard_EXPORT void releaseRenderPass();
+
+protected:
+
+  VkRenderPass myVkRenderPass;
+
+};
+
+#endif // _Vulkan_RenderPass_HeaderFile
diff --git a/src/Vulkan/Vulkan_Shader.cxx b/src/Vulkan/Vulkan_Shader.cxx
new file mode 100644 (file)
index 0000000..8e5171e
--- /dev/null
@@ -0,0 +1,163 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_Shader.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <OSD_OpenFile.hxx>
+#include <Vulkan_Device.hxx>
+
+#include <vulkan/vulkan.h>
+
+#include <memory>
+#include <vector>
+
+namespace
+{
+  //! File sentry.
+  struct FileSentry
+  {
+    FILE* File;
+
+    operator FILE*() const { return File; }
+
+    FileSentry (const TCollection_AsciiString& theFilePath)
+    : File (OSD_OpenFile (theFilePath.ToCString(), "rb")) {}
+
+    ~FileSentry()
+    {
+      if (File != NULL)
+      {
+        fclose (File);
+      }
+    }
+  };
+}
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Shader, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_Shader
+// purpose  :
+// =======================================================================
+Vulkan_Shader::Vulkan_Shader()
+: myVkShader (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Vulkan_Shader
+// purpose  :
+// =======================================================================
+Vulkan_Shader::~Vulkan_Shader()
+{
+  releaseShader();
+}
+
+// =======================================================================
+// function : releaseShader
+// purpose  :
+// =======================================================================
+void Vulkan_Shader::releaseShader()
+{
+  if (myVkShader != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_Shader");
+    vkDestroyShaderModule (myDevice->Device(), myVkShader, myDevice->HostAllocator());
+    myVkShader = NULL;
+  }
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool Vulkan_Shader::Create (const Handle(Vulkan_Device)& theDevice,
+                            const uint32_t* theCode,
+                            uint32_t theNbBytes)
+{
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+
+  VkShaderModuleCreateInfo aVkShaderInfo;
+  aVkShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+  aVkShaderInfo.pNext = NULL;
+  aVkShaderInfo.flags = 0;
+  aVkShaderInfo.pCode = theCode;
+  aVkShaderInfo.codeSize = theNbBytes;
+
+  VkResult aRes = vkCreateShaderModule (theDevice->Device(), &aVkShaderInfo, theDevice->HostAllocator(), &myVkShader);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("failed to create shader object", aRes);
+    return false;
+  }
+
+  return true;
+}
+
+// =======================================================================
+// function : CreateFromFile
+// purpose  :
+// =======================================================================
+bool Vulkan_Shader::CreateFromFile (const Handle(Vulkan_Device)& theDevice,
+                                    const TCollection_AsciiString& theFilePath)
+{
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL)
+  {
+    return false;
+  }
+
+  FileSentry aFile (theFilePath.ToCString());
+  if (aFile.File == NULL)
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Shader, unable to open file '") + theFilePath + "'");
+    return false;
+  }
+
+  uint32_t aFileLen = 0;
+  if (fseek (aFile, 0, SEEK_END) == 0)
+  {
+    aFileLen = (uint32_t )ftell (aFile);
+    if (fseek (aFile, 0, SEEK_SET) != 0)
+    {
+      aFileLen = 0;
+    }
+  }
+  if (aFileLen % 4 != 0
+   || aFileLen == 0)
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Shader, file '") + theFilePath + "' has wrong length " + (int )aFileLen);
+    return false;
+  }
+
+  std::vector<uint32_t> aCode (aFileLen / 4);
+  if (fread (aCode.data(), 1, aFileLen, aFile) != aFileLen)
+  {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Shader, unable to read file '") + theFilePath + "'");
+    return false;
+  }
+  
+  return Create (theDevice, aCode.data(), aFileLen);
+}
diff --git a/src/Vulkan/Vulkan_Shader.hxx b/src/Vulkan/Vulkan_Shader.hxx
new file mode 100644 (file)
index 0000000..8bc117a
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Shader_HeaderFile
+#define _Vulkan_Shader_HeaderFile
+
+#include <Vulkan_Object.hxx>
+
+class TCollection_AsciiString;
+
+//! This class defines an Vulkan shader.
+class Vulkan_Shader : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Shader, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_Shader();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_Shader();
+
+  //! Return shader.
+  VkShaderModule Shader() const { return myVkShader; }
+
+  //! Create the object, @sa vkCreateShaderModule().
+  Standard_EXPORT bool Create (const Handle(Vulkan_Device)& theDevice,
+                               const uint32_t* theCode,
+                               uint32_t theNbBytes);
+
+  //! Create the object, @sa vkCreateShaderModule().
+  Standard_EXPORT bool CreateFromFile (const Handle(Vulkan_Device)& theDevice,
+                                       const TCollection_AsciiString& theFilePath);
+
+protected:
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releaseShader(); }
+
+  //! Release the object, @sa vkDestroyShaderModule().
+  Standard_EXPORT void releaseShader();
+
+protected:
+
+  VkShaderModule myVkShader;
+
+};
+
+#endif // _Vulkan_Shader_HeaderFile
diff --git a/src/Vulkan/Vulkan_ShaderFlat.fs b/src/Vulkan/Vulkan_ShaderFlat.fs
new file mode 100644 (file)
index 0000000..c89455f
--- /dev/null
@@ -0,0 +1,73 @@
+#version 450
+
+layout(std140, binding=0) uniform Colors
+{
+  mat4 occWorldViewMatrix;  //!< World-view  matrix
+  mat4 occProjectionMatrix; //!< Projection  matrix
+  mat4 occModelWorldMatrix; //!< Model-world matrix
+  vec4 uColor;
+};
+
+layout(location = 0) in vec4 PositionWorld;
+layout(location = 1) in vec4 Position;
+layout(location = 2) in vec3 View;
+
+layout(location = 0) out vec4 occFragColor0;
+
+vec3 Normal;
+vec3 Ambient;
+vec3 Diffuse;
+vec3 Specular;
+void directionalLightFirst (in vec3 theNormal,
+                            in vec3 theView,
+                            in bool theIsFront)
+{
+  vec3 aLight = normalize (vec3 (0.0, 0.0, 1.0));
+  //if (occLight_IsHeadlight (0) == 0)
+  {
+    //aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));
+  }
+
+  vec3 aHalf = normalize (aLight + theView);
+
+  vec3  aFaceSideNormal = theIsFront ? theNormal : -theNormal;
+  float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
+  float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
+
+  float aSpecl = 0.0;
+  if (aNdotL > 0.0)
+  {
+    aSpecl = pow (aNdotH, 128.0 * 0.65);
+  }
+
+  Diffuse  += vec3(1.0, 1.0, 1.0) * aNdotL;
+  Specular += vec3(1.0, 1.0, 1.0) * aSpecl;
+}
+
+vec4 computeLighting (in vec3 theNormal,
+                      in vec3 theView,
+                      in vec4 thePoint,
+                      in bool theIsFront)
+{
+  Ambient  = vec3 (1.0, 1.0, 1.0);
+  Diffuse  = vec3 (0.0);
+  Specular = vec3 (0.0);
+  vec3 aPoint = thePoint.xyz / thePoint.w;
+    directionalLightFirst(theNormal, theView, theIsFront);
+  vec4 aMatAmbient  = vec4 (0.329, 0.224, 0.027, 1.0);
+  vec4 aMatDiffuse  = vec4 (0.780, 0.569, 0.114, 1.0);
+  vec4 aMatSpecular = vec4 (0.992, 0.941, 0.808, 1.0);
+  vec4 aMatEmission = vec4 (0.0, 0.0, 0.0, 0.0);
+  vec3 aColor = Ambient  * aMatAmbient.rgb
+              + Diffuse  * aMatDiffuse.rgb
+              + Specular * aMatSpecular.rgb
+                         + aMatEmission.rgb;
+  return vec4 (aColor, aMatDiffuse.a);
+}
+
+void main()
+{
+  Normal = normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));
+  if (!gl_FrontFacing) { Normal = -Normal; }
+  occFragColor0 = computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing);;
+}
diff --git a/src/Vulkan/Vulkan_ShaderFlat.vs b/src/Vulkan/Vulkan_ShaderFlat.vs
new file mode 100644 (file)
index 0000000..9e8fca5
--- /dev/null
@@ -0,0 +1,23 @@
+#version 450
+
+layout(std140, binding=0) uniform Colors
+{
+  mat4 occWorldViewMatrix;  //!< World-view  matrix
+  mat4 occProjectionMatrix; //!< Projection  matrix
+  mat4 occModelWorldMatrix; //!< Model-world matrix
+  vec4 uColor;
+};
+
+layout(location = 0) in vec4 occVertex;
+
+layout(location = 0) out vec4 PositionWorld;
+layout(location = 1) out vec4 Position;
+layout(location = 2) out vec3 View;
+
+void main()
+{
+  PositionWorld = occModelWorldMatrix * occVertex;
+  Position      = occWorldViewMatrix * PositionWorld;
+  View          = vec3 (0.0, 0.0, 1.0);
+  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;
+}
diff --git a/src/Vulkan/Vulkan_ShaderFlat_fs_spv.pxx b/src/Vulkan/Vulkan_ShaderFlat_fs_spv.pxx
new file mode 100644 (file)
index 0000000..57e7c69
--- /dev/null
@@ -0,0 +1,163 @@
+       // 7.11.3113
+        #pragma once
+const uint32_t Vulkan_ShaderFlat_fs_spv[] = {
+       0x07230203,0x00010000,0x00080007,0x000000ba,0x00000000,0x00020011,0x00000001,0x0006000b,
+       0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+       0x000a000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000008c,0x0000009f,0x000000a7,
+       0x000000ab,0x000000b9,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,
+       0x00040005,0x00000004,0x6e69616d,0x00000000,0x000b0005,0x0000000f,0x65726964,0x6f697463,
+       0x4c6c616e,0x74686769,0x73726946,0x66762874,0x66763b33,0x31623b33,0x0000003b,0x00050005,
+       0x0000000c,0x4e656874,0x616d726f,0x0000006c,0x00040005,0x0000000d,0x56656874,0x00776569,
+       0x00050005,0x0000000e,0x49656874,0x6f724673,0x0000746e,0x000a0005,0x00000018,0x706d6f63,
+       0x4c657475,0x74686769,0x28676e69,0x3b336676,0x3b336676,0x3b346676,0x003b3162,0x00050005,
+       0x00000014,0x4e656874,0x616d726f,0x0000006c,0x00040005,0x00000015,0x56656874,0x00776569,
+       0x00050005,0x00000016,0x50656874,0x746e696f,0x00000000,0x00050005,0x00000017,0x49656874,
+       0x6f724673,0x0000746e,0x00040005,0x0000001a,0x67694c61,0x00007468,0x00040005,0x0000001e,
+       0x6c614861,0x00000066,0x00060005,0x00000023,0x63614661,0x64695365,0x726f4e65,0x006c616d,
+       0x00040005,0x0000002e,0x6f644e61,0x00004c74,0x00040005,0x00000033,0x6f644e61,0x00004874,
+       0x00040005,0x00000038,0x65705361,0x00006c63,0x00040005,0x00000041,0x66666944,0x00657375,
+       0x00050005,0x00000047,0x63657053,0x72616c75,0x00000000,0x00040005,0x0000004c,0x69626d41,
+       0x00746e65,0x00040005,0x0000004e,0x696f5061,0x0000746e,0x00040005,0x00000057,0x61726170,
+       0x0000006d,0x00040005,0x00000059,0x61726170,0x0000006d,0x00040005,0x0000005b,0x61726170,
+       0x0000006d,0x00050005,0x0000005e,0x74614d61,0x69626d41,0x00746e65,0x00050005,0x00000063,
+       0x74614d61,0x66666944,0x00657375,0x00060005,0x00000068,0x74614d61,0x63657053,0x72616c75,
+       0x00000000,0x00060005,0x0000006d,0x74614d61,0x73696d45,0x6e6f6973,0x00000000,0x00040005,
+       0x0000006f,0x6c6f4361,0x0000726f,0x00040005,0x0000008a,0x6d726f4e,0x00006c61,0x00050005,
+       0x0000008c,0x69736f50,0x6e6f6974,0x00000000,0x00060005,0x0000009f,0x465f6c67,0x746e6f72,
+       0x69636146,0x0000676e,0x00060005,0x000000a7,0x4663636f,0x43676172,0x726f6c6f,0x00000030,
+       0x00040005,0x000000ab,0x77656956,0x00000000,0x00040005,0x000000ae,0x61726170,0x0000006d,
+       0x00040005,0x000000af,0x61726170,0x0000006d,0x00040005,0x000000b0,0x61726170,0x0000006d,
+       0x00040005,0x000000b2,0x61726170,0x0000006d,0x00040005,0x000000b6,0x6f6c6f43,0x00007372,
+       0x00080006,0x000000b6,0x00000000,0x5763636f,0x646c726f,0x77656956,0x7274614d,0x00007869,
+       0x00080006,0x000000b6,0x00000001,0x5063636f,0x656a6f72,0x6f697463,0x74614d6e,0x00786972,
+       0x00080006,0x000000b6,0x00000002,0x4d63636f,0x6c65646f,0x6c726f57,0x74614d64,0x00786972,
+       0x00050006,0x000000b6,0x00000003,0x6c6f4375,0x0000726f,0x00030005,0x000000b8,0x00000000,
+       0x00060005,0x000000b9,0x69736f50,0x6e6f6974,0x6c726f57,0x00000064,0x00040047,0x0000008c,
+       0x0000001e,0x00000001,0x00040047,0x0000009f,0x0000000b,0x00000011,0x00040047,0x000000a7,
+       0x0000001e,0x00000000,0x00040047,0x000000ab,0x0000001e,0x00000002,0x00040048,0x000000b6,
+       0x00000000,0x00000005,0x00050048,0x000000b6,0x00000000,0x00000023,0x00000000,0x00050048,
+       0x000000b6,0x00000000,0x00000007,0x00000010,0x00040048,0x000000b6,0x00000001,0x00000005,
+       0x00050048,0x000000b6,0x00000001,0x00000023,0x00000040,0x00050048,0x000000b6,0x00000001,
+       0x00000007,0x00000010,0x00040048,0x000000b6,0x00000002,0x00000005,0x00050048,0x000000b6,
+       0x00000002,0x00000023,0x00000080,0x00050048,0x000000b6,0x00000002,0x00000007,0x00000010,
+       0x00050048,0x000000b6,0x00000003,0x00000023,0x000000c0,0x00030047,0x000000b6,0x00000002,
+       0x00040047,0x000000b8,0x00000022,0x00000000,0x00040047,0x000000b8,0x00000021,0x00000000,
+       0x00040047,0x000000b9,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,
+       0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000003,
+       0x00040020,0x00000008,0x00000007,0x00000007,0x00020014,0x00000009,0x00040020,0x0000000a,
+       0x00000007,0x00000009,0x00060021,0x0000000b,0x00000002,0x00000008,0x00000008,0x0000000a,
+       0x00040017,0x00000011,0x00000006,0x00000004,0x00040020,0x00000012,0x00000007,0x00000011,
+       0x00070021,0x00000013,0x00000011,0x00000008,0x00000008,0x00000012,0x0000000a,0x0004002b,
+       0x00000006,0x0000001b,0x00000000,0x0004002b,0x00000006,0x0000001c,0x3f800000,0x0006002c,
+       0x00000007,0x0000001d,0x0000001b,0x0000001b,0x0000001c,0x00040020,0x0000002d,0x00000007,
+       0x00000006,0x0004002b,0x00000006,0x0000003e,0x42a66666,0x00040020,0x00000040,0x00000006,
+       0x00000007,0x0004003b,0x00000040,0x00000041,0x00000006,0x0006002c,0x00000007,0x00000042,
+       0x0000001c,0x0000001c,0x0000001c,0x0004003b,0x00000040,0x00000047,0x00000006,0x0004003b,
+       0x00000040,0x0000004c,0x00000006,0x0006002c,0x00000007,0x0000004d,0x0000001b,0x0000001b,
+       0x0000001b,0x00040015,0x00000051,0x00000020,0x00000000,0x0004002b,0x00000051,0x00000052,
+       0x00000003,0x0004002b,0x00000006,0x0000005f,0x3ea872b0,0x0004002b,0x00000006,0x00000060,
+       0x3e656042,0x0004002b,0x00000006,0x00000061,0x3cdd2f1b,0x0007002c,0x00000011,0x00000062,
+       0x0000005f,0x00000060,0x00000061,0x0000001c,0x0004002b,0x00000006,0x00000064,0x3f47ae14,
+       0x0004002b,0x00000006,0x00000065,0x3f11a9fc,0x0004002b,0x00000006,0x00000066,0x3de978d5,
+       0x0007002c,0x00000011,0x00000067,0x00000064,0x00000065,0x00000066,0x0000001c,0x0004002b,
+       0x00000006,0x00000069,0x3f7df3b6,0x0004002b,0x00000006,0x0000006a,0x3f70e560,0x0004002b,
+       0x00000006,0x0000006b,0x3f4ed917,0x0007002c,0x00000011,0x0000006c,0x00000069,0x0000006a,
+       0x0000006b,0x0000001c,0x0007002c,0x00000011,0x0000006e,0x0000001b,0x0000001b,0x0000001b,
+       0x0000001b,0x0004003b,0x00000040,0x0000008a,0x00000006,0x00040020,0x0000008b,0x00000001,
+       0x00000011,0x0004003b,0x0000008b,0x0000008c,0x00000001,0x00040020,0x0000008f,0x00000001,
+       0x00000006,0x00040020,0x0000009e,0x00000001,0x00000009,0x0004003b,0x0000009e,0x0000009f,
+       0x00000001,0x00040020,0x000000a6,0x00000003,0x00000011,0x0004003b,0x000000a6,0x000000a7,
+       0x00000003,0x00040020,0x000000aa,0x00000001,0x00000007,0x0004003b,0x000000aa,0x000000ab,
+       0x00000001,0x00040018,0x000000b5,0x00000011,0x00000004,0x0006001e,0x000000b6,0x000000b5,
+       0x000000b5,0x000000b5,0x00000011,0x00040020,0x000000b7,0x00000002,0x000000b6,0x0004003b,
+       0x000000b7,0x000000b8,0x00000002,0x0004003b,0x0000008b,0x000000b9,0x00000001,0x00050036,
+       0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000008,
+       0x000000ae,0x00000007,0x0004003b,0x00000008,0x000000af,0x00000007,0x0004003b,0x00000012,
+       0x000000b0,0x00000007,0x0004003b,0x0000000a,0x000000b2,0x00000007,0x0004003d,0x00000011,
+       0x0000008d,0x0000008c,0x0008004f,0x00000007,0x0000008e,0x0000008d,0x0000008d,0x00000000,
+       0x00000001,0x00000002,0x00050041,0x0000008f,0x00000090,0x0000008c,0x00000052,0x0004003d,
+       0x00000006,0x00000091,0x00000090,0x00060050,0x00000007,0x00000092,0x00000091,0x00000091,
+       0x00000091,0x00050088,0x00000007,0x00000093,0x0000008e,0x00000092,0x000400cf,0x00000007,
+       0x00000094,0x00000093,0x0004003d,0x00000011,0x00000095,0x0000008c,0x0008004f,0x00000007,
+       0x00000096,0x00000095,0x00000095,0x00000000,0x00000001,0x00000002,0x00050041,0x0000008f,
+       0x00000097,0x0000008c,0x00000052,0x0004003d,0x00000006,0x00000098,0x00000097,0x00060050,
+       0x00000007,0x00000099,0x00000098,0x00000098,0x00000098,0x00050088,0x00000007,0x0000009a,
+       0x00000096,0x00000099,0x000400d0,0x00000007,0x0000009b,0x0000009a,0x0007000c,0x00000007,
+       0x0000009c,0x00000001,0x00000044,0x00000094,0x0000009b,0x0006000c,0x00000007,0x0000009d,
+       0x00000001,0x00000045,0x0000009c,0x0003003e,0x0000008a,0x0000009d,0x0004003d,0x00000009,
+       0x000000a0,0x0000009f,0x000400a8,0x00000009,0x000000a1,0x000000a0,0x000300f7,0x000000a3,
+       0x00000000,0x000400fa,0x000000a1,0x000000a2,0x000000a3,0x000200f8,0x000000a2,0x0004003d,
+       0x00000007,0x000000a4,0x0000008a,0x0004007f,0x00000007,0x000000a5,0x000000a4,0x0003003e,
+       0x0000008a,0x000000a5,0x000200f9,0x000000a3,0x000200f8,0x000000a3,0x0004003d,0x00000007,
+       0x000000a8,0x0000008a,0x0006000c,0x00000007,0x000000a9,0x00000001,0x00000045,0x000000a8,
+       0x0004003d,0x00000007,0x000000ac,0x000000ab,0x0006000c,0x00000007,0x000000ad,0x00000001,
+       0x00000045,0x000000ac,0x0003003e,0x000000ae,0x000000a9,0x0003003e,0x000000af,0x000000ad,
+       0x0004003d,0x00000011,0x000000b1,0x0000008c,0x0003003e,0x000000b0,0x000000b1,0x0004003d,
+       0x00000009,0x000000b3,0x0000009f,0x0003003e,0x000000b2,0x000000b3,0x00080039,0x00000011,
+       0x000000b4,0x00000018,0x000000ae,0x000000af,0x000000b0,0x000000b2,0x0003003e,0x000000a7,
+       0x000000b4,0x000100fd,0x00010038,0x00050036,0x00000002,0x0000000f,0x00000000,0x0000000b,
+       0x00030037,0x00000008,0x0000000c,0x00030037,0x00000008,0x0000000d,0x00030037,0x0000000a,
+       0x0000000e,0x000200f8,0x00000010,0x0004003b,0x00000008,0x0000001a,0x00000007,0x0004003b,
+       0x00000008,0x0000001e,0x00000007,0x0004003b,0x00000008,0x00000023,0x00000007,0x0004003b,
+       0x00000008,0x00000025,0x00000007,0x0004003b,0x0000002d,0x0000002e,0x00000007,0x0004003b,
+       0x0000002d,0x00000033,0x00000007,0x0004003b,0x0000002d,0x00000038,0x00000007,0x0003003e,
+       0x0000001a,0x0000001d,0x0004003d,0x00000007,0x0000001f,0x0000001a,0x0004003d,0x00000007,
+       0x00000020,0x0000000d,0x00050081,0x00000007,0x00000021,0x0000001f,0x00000020,0x0006000c,
+       0x00000007,0x00000022,0x00000001,0x00000045,0x00000021,0x0003003e,0x0000001e,0x00000022,
+       0x0004003d,0x00000009,0x00000024,0x0000000e,0x000300f7,0x00000027,0x00000000,0x000400fa,
+       0x00000024,0x00000026,0x00000029,0x000200f8,0x00000026,0x0004003d,0x00000007,0x00000028,
+       0x0000000c,0x0003003e,0x00000025,0x00000028,0x000200f9,0x00000027,0x000200f8,0x00000029,
+       0x0004003d,0x00000007,0x0000002a,0x0000000c,0x0004007f,0x00000007,0x0000002b,0x0000002a,
+       0x0003003e,0x00000025,0x0000002b,0x000200f9,0x00000027,0x000200f8,0x00000027,0x0004003d,
+       0x00000007,0x0000002c,0x00000025,0x0003003e,0x00000023,0x0000002c,0x0004003d,0x00000007,
+       0x0000002f,0x00000023,0x0004003d,0x00000007,0x00000030,0x0000001a,0x00050094,0x00000006,
+       0x00000031,0x0000002f,0x00000030,0x0007000c,0x00000006,0x00000032,0x00000001,0x00000028,
+       0x0000001b,0x00000031,0x0003003e,0x0000002e,0x00000032,0x0004003d,0x00000007,0x00000034,
+       0x00000023,0x0004003d,0x00000007,0x00000035,0x0000001e,0x00050094,0x00000006,0x00000036,
+       0x00000034,0x00000035,0x0007000c,0x00000006,0x00000037,0x00000001,0x00000028,0x0000001b,
+       0x00000036,0x0003003e,0x00000033,0x00000037,0x0003003e,0x00000038,0x0000001b,0x0004003d,
+       0x00000006,0x00000039,0x0000002e,0x000500ba,0x00000009,0x0000003a,0x00000039,0x0000001b,
+       0x000300f7,0x0000003c,0x00000000,0x000400fa,0x0000003a,0x0000003b,0x0000003c,0x000200f8,
+       0x0000003b,0x0004003d,0x00000006,0x0000003d,0x00000033,0x0007000c,0x00000006,0x0000003f,
+       0x00000001,0x0000001a,0x0000003d,0x0000003e,0x0003003e,0x00000038,0x0000003f,0x000200f9,
+       0x0000003c,0x000200f8,0x0000003c,0x0004003d,0x00000006,0x00000043,0x0000002e,0x0005008e,
+       0x00000007,0x00000044,0x00000042,0x00000043,0x0004003d,0x00000007,0x00000045,0x00000041,
+       0x00050081,0x00000007,0x00000046,0x00000045,0x00000044,0x0003003e,0x00000041,0x00000046,
+       0x0004003d,0x00000006,0x00000048,0x00000038,0x0005008e,0x00000007,0x00000049,0x00000042,
+       0x00000048,0x0004003d,0x00000007,0x0000004a,0x00000047,0x00050081,0x00000007,0x0000004b,
+       0x0000004a,0x00000049,0x0003003e,0x00000047,0x0000004b,0x000100fd,0x00010038,0x00050036,
+       0x00000011,0x00000018,0x00000000,0x00000013,0x00030037,0x00000008,0x00000014,0x00030037,
+       0x00000008,0x00000015,0x00030037,0x00000012,0x00000016,0x00030037,0x0000000a,0x00000017,
+       0x000200f8,0x00000019,0x0004003b,0x00000008,0x0000004e,0x00000007,0x0004003b,0x00000008,
+       0x00000057,0x00000007,0x0004003b,0x00000008,0x00000059,0x00000007,0x0004003b,0x0000000a,
+       0x0000005b,0x00000007,0x0004003b,0x00000012,0x0000005e,0x00000007,0x0004003b,0x00000012,
+       0x00000063,0x00000007,0x0004003b,0x00000012,0x00000068,0x00000007,0x0004003b,0x00000012,
+       0x0000006d,0x00000007,0x0004003b,0x00000008,0x0000006f,0x00000007,0x0003003e,0x0000004c,
+       0x00000042,0x0003003e,0x00000041,0x0000004d,0x0003003e,0x00000047,0x0000004d,0x0004003d,
+       0x00000011,0x0000004f,0x00000016,0x0008004f,0x00000007,0x00000050,0x0000004f,0x0000004f,
+       0x00000000,0x00000001,0x00000002,0x00050041,0x0000002d,0x00000053,0x00000016,0x00000052,
+       0x0004003d,0x00000006,0x00000054,0x00000053,0x00060050,0x00000007,0x00000055,0x00000054,
+       0x00000054,0x00000054,0x00050088,0x00000007,0x00000056,0x00000050,0x00000055,0x0003003e,
+       0x0000004e,0x00000056,0x0004003d,0x00000007,0x00000058,0x00000014,0x0003003e,0x00000057,
+       0x00000058,0x0004003d,0x00000007,0x0000005a,0x00000015,0x0003003e,0x00000059,0x0000005a,
+       0x0004003d,0x00000009,0x0000005c,0x00000017,0x0003003e,0x0000005b,0x0000005c,0x00070039,
+       0x00000002,0x0000005d,0x0000000f,0x00000057,0x00000059,0x0000005b,0x0003003e,0x0000005e,
+       0x00000062,0x0003003e,0x00000063,0x00000067,0x0003003e,0x00000068,0x0000006c,0x0003003e,
+       0x0000006d,0x0000006e,0x0004003d,0x00000007,0x00000070,0x0000004c,0x0004003d,0x00000011,
+       0x00000071,0x0000005e,0x0008004f,0x00000007,0x00000072,0x00000071,0x00000071,0x00000000,
+       0x00000001,0x00000002,0x00050085,0x00000007,0x00000073,0x00000070,0x00000072,0x0004003d,
+       0x00000007,0x00000074,0x00000041,0x0004003d,0x00000011,0x00000075,0x00000063,0x0008004f,
+       0x00000007,0x00000076,0x00000075,0x00000075,0x00000000,0x00000001,0x00000002,0x00050085,
+       0x00000007,0x00000077,0x00000074,0x00000076,0x00050081,0x00000007,0x00000078,0x00000073,
+       0x00000077,0x0004003d,0x00000007,0x00000079,0x00000047,0x0004003d,0x00000011,0x0000007a,
+       0x00000068,0x0008004f,0x00000007,0x0000007b,0x0000007a,0x0000007a,0x00000000,0x00000001,
+       0x00000002,0x00050085,0x00000007,0x0000007c,0x00000079,0x0000007b,0x00050081,0x00000007,
+       0x0000007d,0x00000078,0x0000007c,0x0004003d,0x00000011,0x0000007e,0x0000006d,0x0008004f,
+       0x00000007,0x0000007f,0x0000007e,0x0000007e,0x00000000,0x00000001,0x00000002,0x00050081,
+       0x00000007,0x00000080,0x0000007d,0x0000007f,0x0003003e,0x0000006f,0x00000080,0x0004003d,
+       0x00000007,0x00000081,0x0000006f,0x00050041,0x0000002d,0x00000082,0x00000063,0x00000052,
+       0x0004003d,0x00000006,0x00000083,0x00000082,0x00050051,0x00000006,0x00000084,0x00000081,
+       0x00000000,0x00050051,0x00000006,0x00000085,0x00000081,0x00000001,0x00050051,0x00000006,
+       0x00000086,0x00000081,0x00000002,0x00070050,0x00000011,0x00000087,0x00000084,0x00000085,
+       0x00000086,0x00000083,0x000200fe,0x00000087,0x00010038
+};
\ No newline at end of file
diff --git a/src/Vulkan/Vulkan_ShaderFlat_vs_spv.pxx b/src/Vulkan/Vulkan_ShaderFlat_vs_spv.pxx
new file mode 100644 (file)
index 0000000..bfe7bde
--- /dev/null
@@ -0,0 +1,61 @@
+       // 7.11.3113
+        #pragma once
+const uint32_t Vulkan_ShaderFlat_vs_spv[] = {
+       0x07230203,0x00010000,0x00080007,0x00000035,0x00000000,0x00020011,0x00000001,0x0006000b,
+       0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+       0x000a000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000009,0x00000014,0x00000017,
+       0x0000001f,0x00000028,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,
+       0x00000000,0x00060005,0x00000009,0x69736f50,0x6e6f6974,0x6c726f57,0x00000064,0x00040005,
+       0x0000000b,0x6f6c6f43,0x00007372,0x00080006,0x0000000b,0x00000000,0x5763636f,0x646c726f,
+       0x77656956,0x7274614d,0x00007869,0x00080006,0x0000000b,0x00000001,0x5063636f,0x656a6f72,
+       0x6f697463,0x74614d6e,0x00786972,0x00080006,0x0000000b,0x00000002,0x4d63636f,0x6c65646f,
+       0x6c726f57,0x74614d64,0x00786972,0x00050006,0x0000000b,0x00000003,0x6c6f4375,0x0000726f,
+       0x00030005,0x0000000d,0x00000000,0x00050005,0x00000014,0x5663636f,0x65747265,0x00000078,
+       0x00050005,0x00000017,0x69736f50,0x6e6f6974,0x00000000,0x00040005,0x0000001f,0x77656956,
+       0x00000000,0x00060005,0x00000026,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,
+       0x00000026,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000026,0x00000001,
+       0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000026,0x00000002,0x435f6c67,
+       0x4470696c,0x61747369,0x0065636e,0x00070006,0x00000026,0x00000003,0x435f6c67,0x446c6c75,
+       0x61747369,0x0065636e,0x00030005,0x00000028,0x00000000,0x00040047,0x00000009,0x0000001e,
+       0x00000000,0x00040048,0x0000000b,0x00000000,0x00000005,0x00050048,0x0000000b,0x00000000,
+       0x00000023,0x00000000,0x00050048,0x0000000b,0x00000000,0x00000007,0x00000010,0x00040048,
+       0x0000000b,0x00000001,0x00000005,0x00050048,0x0000000b,0x00000001,0x00000023,0x00000040,
+       0x00050048,0x0000000b,0x00000001,0x00000007,0x00000010,0x00040048,0x0000000b,0x00000002,
+       0x00000005,0x00050048,0x0000000b,0x00000002,0x00000023,0x00000080,0x00050048,0x0000000b,
+       0x00000002,0x00000007,0x00000010,0x00050048,0x0000000b,0x00000003,0x00000023,0x000000c0,
+       0x00030047,0x0000000b,0x00000002,0x00040047,0x0000000d,0x00000022,0x00000000,0x00040047,
+       0x0000000d,0x00000021,0x00000000,0x00040047,0x00000014,0x0000001e,0x00000000,0x00040047,
+       0x00000017,0x0000001e,0x00000001,0x00040047,0x0000001f,0x0000001e,0x00000002,0x00050048,
+       0x00000026,0x00000000,0x0000000b,0x00000000,0x00050048,0x00000026,0x00000001,0x0000000b,
+       0x00000001,0x00050048,0x00000026,0x00000002,0x0000000b,0x00000003,0x00050048,0x00000026,
+       0x00000003,0x0000000b,0x00000004,0x00030047,0x00000026,0x00000002,0x00020013,0x00000002,
+       0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,
+       0x00000006,0x00000004,0x00040020,0x00000008,0x00000003,0x00000007,0x0004003b,0x00000008,
+       0x00000009,0x00000003,0x00040018,0x0000000a,0x00000007,0x00000004,0x0006001e,0x0000000b,
+       0x0000000a,0x0000000a,0x0000000a,0x00000007,0x00040020,0x0000000c,0x00000002,0x0000000b,
+       0x0004003b,0x0000000c,0x0000000d,0x00000002,0x00040015,0x0000000e,0x00000020,0x00000001,
+       0x0004002b,0x0000000e,0x0000000f,0x00000002,0x00040020,0x00000010,0x00000002,0x0000000a,
+       0x00040020,0x00000013,0x00000001,0x00000007,0x0004003b,0x00000013,0x00000014,0x00000001,
+       0x0004003b,0x00000008,0x00000017,0x00000003,0x0004002b,0x0000000e,0x00000018,0x00000000,
+       0x00040017,0x0000001d,0x00000006,0x00000003,0x00040020,0x0000001e,0x00000003,0x0000001d,
+       0x0004003b,0x0000001e,0x0000001f,0x00000003,0x0004002b,0x00000006,0x00000020,0x00000000,
+       0x0004002b,0x00000006,0x00000021,0x3f800000,0x0006002c,0x0000001d,0x00000022,0x00000020,
+       0x00000020,0x00000021,0x00040015,0x00000023,0x00000020,0x00000000,0x0004002b,0x00000023,
+       0x00000024,0x00000001,0x0004001c,0x00000025,0x00000006,0x00000024,0x0006001e,0x00000026,
+       0x00000007,0x00000006,0x00000025,0x00000025,0x00040020,0x00000027,0x00000003,0x00000026,
+       0x0004003b,0x00000027,0x00000028,0x00000003,0x0004002b,0x0000000e,0x00000029,0x00000001,
+       0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041,
+       0x00000010,0x00000011,0x0000000d,0x0000000f,0x0004003d,0x0000000a,0x00000012,0x00000011,
+       0x0004003d,0x00000007,0x00000015,0x00000014,0x00050091,0x00000007,0x00000016,0x00000012,
+       0x00000015,0x0003003e,0x00000009,0x00000016,0x00050041,0x00000010,0x00000019,0x0000000d,
+       0x00000018,0x0004003d,0x0000000a,0x0000001a,0x00000019,0x0004003d,0x00000007,0x0000001b,
+       0x00000009,0x00050091,0x00000007,0x0000001c,0x0000001a,0x0000001b,0x0003003e,0x00000017,
+       0x0000001c,0x0003003e,0x0000001f,0x00000022,0x00050041,0x00000010,0x0000002a,0x0000000d,
+       0x00000029,0x0004003d,0x0000000a,0x0000002b,0x0000002a,0x00050041,0x00000010,0x0000002c,
+       0x0000000d,0x00000018,0x0004003d,0x0000000a,0x0000002d,0x0000002c,0x00050092,0x0000000a,
+       0x0000002e,0x0000002b,0x0000002d,0x00050041,0x00000010,0x0000002f,0x0000000d,0x0000000f,
+       0x0004003d,0x0000000a,0x00000030,0x0000002f,0x00050092,0x0000000a,0x00000031,0x0000002e,
+       0x00000030,0x0004003d,0x00000007,0x00000032,0x00000014,0x00050091,0x00000007,0x00000033,
+       0x00000031,0x00000032,0x00050041,0x00000008,0x00000034,0x00000028,0x00000018,0x0003003e,
+       0x00000034,0x00000033,0x000100fd,0x00010038
+};
\ No newline at end of file
diff --git a/src/Vulkan/Vulkan_ShaderPhong.fs b/src/Vulkan/Vulkan_ShaderPhong.fs
new file mode 100644 (file)
index 0000000..d0281b7
--- /dev/null
@@ -0,0 +1,71 @@
+#version 450
+
+layout(std140, binding=0) uniform Colors
+{
+  mat4 occWorldViewMatrix;  //!< World-view  matrix
+  mat4 occProjectionMatrix; //!< Projection  matrix
+  mat4 occModelWorldMatrix; //!< Model-world matrix
+  vec4 uColor;
+};
+
+layout(location = 0) in vec3 Normal;
+layout(location = 1) in vec4 PositionWorld;
+layout(location = 2) in vec4 Position;
+layout(location = 3) in vec3 View;
+
+layout(location = 0) out vec4 occFragColor0;
+
+vec3 Ambient;
+vec3 Diffuse;
+vec3 Specular;
+void directionalLightFirst (in vec3 theNormal,
+                            in vec3 theView,
+                            in bool theIsFront)
+{
+  vec3 aLight = normalize (vec3 (0.0, 0.0, 1.0));
+  //if (occLight_IsHeadlight (0) == 0)
+  {
+    //aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));
+  }
+
+  vec3 aHalf = normalize (aLight + theView);
+
+  vec3  aFaceSideNormal = theIsFront ? theNormal : -theNormal;
+  float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
+  float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
+
+  float aSpecl = 0.0;
+  if (aNdotL > 0.0)
+  {
+    aSpecl = pow (aNdotH, 128.0 * 0.65);
+  }
+
+  Diffuse  += vec3(1.0, 1.0, 1.0) * aNdotL;
+  Specular += vec3(1.0, 1.0, 1.0) * aSpecl;
+}
+
+vec4 computeLighting (in vec3 theNormal,
+                      in vec3 theView,
+                      in vec4 thePoint,
+                      in bool theIsFront)
+{
+  Ambient  = vec3 (1.0, 1.0, 1.0);
+  Diffuse  = vec3 (0.0);
+  Specular = vec3 (0.0);
+  vec3 aPoint = thePoint.xyz / thePoint.w;
+    directionalLightFirst(theNormal, theView, theIsFront);
+  vec4 aMatAmbient  = vec4 (0.329, 0.224, 0.027, 1.0);
+  vec4 aMatDiffuse  = vec4 (0.780, 0.569, 0.114, 1.0);
+  vec4 aMatSpecular = vec4 (0.992, 0.941, 0.808, 1.0);
+  vec4 aMatEmission = vec4 (0.0, 0.0, 0.0, 0.0);
+  vec3 aColor = Ambient  * aMatAmbient.rgb
+              + Diffuse  * aMatDiffuse.rgb
+              + Specular * aMatSpecular.rgb
+                         + aMatEmission.rgb;
+  return vec4 (aColor, aMatDiffuse.a);
+}
+
+void main()
+{
+  occFragColor0 = computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing);;
+}
diff --git a/src/Vulkan/Vulkan_ShaderPhong.vs b/src/Vulkan/Vulkan_ShaderPhong.vs
new file mode 100644 (file)
index 0000000..0030b4a
--- /dev/null
@@ -0,0 +1,36 @@
+#version 450
+
+layout(std140, binding=0) uniform Colors
+{
+  mat4 occWorldViewMatrix;  //!< World-view  matrix
+  mat4 occProjectionMatrix; //!< Projection  matrix
+  mat4 occModelWorldMatrix; //!< Model-world matrix
+  vec4 uColor;
+};
+
+layout(location = 0) in vec4 occVertex;
+layout(location = 1) in vec3 occNormal;
+
+layout(location = 0) out vec3 Normal;
+layout(location = 1) out vec4 PositionWorld;
+layout(location = 2) out vec4 Position;
+layout(location = 3) out vec3 View;
+
+vec3 transformNormal (in vec3 theNormal)
+{
+  mat4 occWorldViewMatrixInverseTranspose  = transpose(inverse(occWorldViewMatrix));
+  mat4 occModelWorldMatrixInverseTranspose = transpose(inverse(occModelWorldMatrix));
+  vec4 aResult = occWorldViewMatrixInverseTranspose
+               * occModelWorldMatrixInverseTranspose
+               * vec4 (theNormal, 0.0);
+  return normalize (aResult.xyz);
+}
+
+void main()
+{
+  PositionWorld = occModelWorldMatrix * occVertex;
+  Position      = occWorldViewMatrix * PositionWorld;
+  View          = vec3 (0.0, 0.0, 1.0);
+  Normal = transformNormal (occNormal);
+  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;
+}
diff --git a/src/Vulkan/Vulkan_ShaderPhong_fs_spv.pxx b/src/Vulkan/Vulkan_ShaderPhong_fs_spv.pxx
new file mode 100644 (file)
index 0000000..35fcacd
--- /dev/null
@@ -0,0 +1,148 @@
+       // 7.11.3113
+        #pragma once
+const uint32_t Vulkan_ShaderPhong_fs_spv[] = {
+       0x07230203,0x00010000,0x00080007,0x000000a3,0x00000000,0x00020011,0x00000001,0x0006000b,
+       0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+       0x000b000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000008b,0x0000008d,0x00000090,
+       0x00000094,0x00000096,0x000000a2,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,
+       0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,0x000b0005,0x0000000f,0x65726964,
+       0x6f697463,0x4c6c616e,0x74686769,0x73726946,0x66762874,0x66763b33,0x31623b33,0x0000003b,
+       0x00050005,0x0000000c,0x4e656874,0x616d726f,0x0000006c,0x00040005,0x0000000d,0x56656874,
+       0x00776569,0x00050005,0x0000000e,0x49656874,0x6f724673,0x0000746e,0x000a0005,0x00000018,
+       0x706d6f63,0x4c657475,0x74686769,0x28676e69,0x3b336676,0x3b336676,0x3b346676,0x003b3162,
+       0x00050005,0x00000014,0x4e656874,0x616d726f,0x0000006c,0x00040005,0x00000015,0x56656874,
+       0x00776569,0x00050005,0x00000016,0x50656874,0x746e696f,0x00000000,0x00050005,0x00000017,
+       0x49656874,0x6f724673,0x0000746e,0x00040005,0x0000001a,0x67694c61,0x00007468,0x00040005,
+       0x0000001e,0x6c614861,0x00000066,0x00060005,0x00000023,0x63614661,0x64695365,0x726f4e65,
+       0x006c616d,0x00040005,0x0000002e,0x6f644e61,0x00004c74,0x00040005,0x00000033,0x6f644e61,
+       0x00004874,0x00040005,0x00000038,0x65705361,0x00006c63,0x00040005,0x00000041,0x66666944,
+       0x00657375,0x00050005,0x00000047,0x63657053,0x72616c75,0x00000000,0x00040005,0x0000004c,
+       0x69626d41,0x00746e65,0x00040005,0x0000004e,0x696f5061,0x0000746e,0x00040005,0x00000057,
+       0x61726170,0x0000006d,0x00040005,0x00000059,0x61726170,0x0000006d,0x00040005,0x0000005b,
+       0x61726170,0x0000006d,0x00050005,0x0000005e,0x74614d61,0x69626d41,0x00746e65,0x00050005,
+       0x00000063,0x74614d61,0x66666944,0x00657375,0x00060005,0x00000068,0x74614d61,0x63657053,
+       0x72616c75,0x00000000,0x00060005,0x0000006d,0x74614d61,0x73696d45,0x6e6f6973,0x00000000,
+       0x00040005,0x0000006f,0x6c6f4361,0x0000726f,0x00060005,0x0000008b,0x4663636f,0x43676172,
+       0x726f6c6f,0x00000030,0x00040005,0x0000008d,0x6d726f4e,0x00006c61,0x00040005,0x00000090,
+       0x77656956,0x00000000,0x00050005,0x00000094,0x69736f50,0x6e6f6974,0x00000000,0x00060005,
+       0x00000096,0x465f6c67,0x746e6f72,0x69636146,0x0000676e,0x00040005,0x00000097,0x61726170,
+       0x0000006d,0x00040005,0x00000098,0x61726170,0x0000006d,0x00040005,0x00000099,0x61726170,
+       0x0000006d,0x00040005,0x0000009b,0x61726170,0x0000006d,0x00040005,0x0000009f,0x6f6c6f43,
+       0x00007372,0x00080006,0x0000009f,0x00000000,0x5763636f,0x646c726f,0x77656956,0x7274614d,
+       0x00007869,0x00080006,0x0000009f,0x00000001,0x5063636f,0x656a6f72,0x6f697463,0x74614d6e,
+       0x00786972,0x00080006,0x0000009f,0x00000002,0x4d63636f,0x6c65646f,0x6c726f57,0x74614d64,
+       0x00786972,0x00050006,0x0000009f,0x00000003,0x6c6f4375,0x0000726f,0x00030005,0x000000a1,
+       0x00000000,0x00060005,0x000000a2,0x69736f50,0x6e6f6974,0x6c726f57,0x00000064,0x00040047,
+       0x0000008b,0x0000001e,0x00000000,0x00040047,0x0000008d,0x0000001e,0x00000000,0x00040047,
+       0x00000090,0x0000001e,0x00000003,0x00040047,0x00000094,0x0000001e,0x00000002,0x00040047,
+       0x00000096,0x0000000b,0x00000011,0x00040048,0x0000009f,0x00000000,0x00000005,0x00050048,
+       0x0000009f,0x00000000,0x00000023,0x00000000,0x00050048,0x0000009f,0x00000000,0x00000007,
+       0x00000010,0x00040048,0x0000009f,0x00000001,0x00000005,0x00050048,0x0000009f,0x00000001,
+       0x00000023,0x00000040,0x00050048,0x0000009f,0x00000001,0x00000007,0x00000010,0x00040048,
+       0x0000009f,0x00000002,0x00000005,0x00050048,0x0000009f,0x00000002,0x00000023,0x00000080,
+       0x00050048,0x0000009f,0x00000002,0x00000007,0x00000010,0x00050048,0x0000009f,0x00000003,
+       0x00000023,0x000000c0,0x00030047,0x0000009f,0x00000002,0x00040047,0x000000a1,0x00000022,
+       0x00000000,0x00040047,0x000000a1,0x00000021,0x00000000,0x00040047,0x000000a2,0x0000001e,
+       0x00000001,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,
+       0x00000020,0x00040017,0x00000007,0x00000006,0x00000003,0x00040020,0x00000008,0x00000007,
+       0x00000007,0x00020014,0x00000009,0x00040020,0x0000000a,0x00000007,0x00000009,0x00060021,
+       0x0000000b,0x00000002,0x00000008,0x00000008,0x0000000a,0x00040017,0x00000011,0x00000006,
+       0x00000004,0x00040020,0x00000012,0x00000007,0x00000011,0x00070021,0x00000013,0x00000011,
+       0x00000008,0x00000008,0x00000012,0x0000000a,0x0004002b,0x00000006,0x0000001b,0x00000000,
+       0x0004002b,0x00000006,0x0000001c,0x3f800000,0x0006002c,0x00000007,0x0000001d,0x0000001b,
+       0x0000001b,0x0000001c,0x00040020,0x0000002d,0x00000007,0x00000006,0x0004002b,0x00000006,
+       0x0000003e,0x42a66666,0x00040020,0x00000040,0x00000006,0x00000007,0x0004003b,0x00000040,
+       0x00000041,0x00000006,0x0006002c,0x00000007,0x00000042,0x0000001c,0x0000001c,0x0000001c,
+       0x0004003b,0x00000040,0x00000047,0x00000006,0x0004003b,0x00000040,0x0000004c,0x00000006,
+       0x0006002c,0x00000007,0x0000004d,0x0000001b,0x0000001b,0x0000001b,0x00040015,0x00000051,
+       0x00000020,0x00000000,0x0004002b,0x00000051,0x00000052,0x00000003,0x0004002b,0x00000006,
+       0x0000005f,0x3ea872b0,0x0004002b,0x00000006,0x00000060,0x3e656042,0x0004002b,0x00000006,
+       0x00000061,0x3cdd2f1b,0x0007002c,0x00000011,0x00000062,0x0000005f,0x00000060,0x00000061,
+       0x0000001c,0x0004002b,0x00000006,0x00000064,0x3f47ae14,0x0004002b,0x00000006,0x00000065,
+       0x3f11a9fc,0x0004002b,0x00000006,0x00000066,0x3de978d5,0x0007002c,0x00000011,0x00000067,
+       0x00000064,0x00000065,0x00000066,0x0000001c,0x0004002b,0x00000006,0x00000069,0x3f7df3b6,
+       0x0004002b,0x00000006,0x0000006a,0x3f70e560,0x0004002b,0x00000006,0x0000006b,0x3f4ed917,
+       0x0007002c,0x00000011,0x0000006c,0x00000069,0x0000006a,0x0000006b,0x0000001c,0x0007002c,
+       0x00000011,0x0000006e,0x0000001b,0x0000001b,0x0000001b,0x0000001b,0x00040020,0x0000008a,
+       0x00000003,0x00000011,0x0004003b,0x0000008a,0x0000008b,0x00000003,0x00040020,0x0000008c,
+       0x00000001,0x00000007,0x0004003b,0x0000008c,0x0000008d,0x00000001,0x0004003b,0x0000008c,
+       0x00000090,0x00000001,0x00040020,0x00000093,0x00000001,0x00000011,0x0004003b,0x00000093,
+       0x00000094,0x00000001,0x00040020,0x00000095,0x00000001,0x00000009,0x0004003b,0x00000095,
+       0x00000096,0x00000001,0x00040018,0x0000009e,0x00000011,0x00000004,0x0006001e,0x0000009f,
+       0x0000009e,0x0000009e,0x0000009e,0x00000011,0x00040020,0x000000a0,0x00000002,0x0000009f,
+       0x0004003b,0x000000a0,0x000000a1,0x00000002,0x0004003b,0x00000093,0x000000a2,0x00000001,
+       0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,
+       0x00000008,0x00000097,0x00000007,0x0004003b,0x00000008,0x00000098,0x00000007,0x0004003b,
+       0x00000012,0x00000099,0x00000007,0x0004003b,0x0000000a,0x0000009b,0x00000007,0x0004003d,
+       0x00000007,0x0000008e,0x0000008d,0x0006000c,0x00000007,0x0000008f,0x00000001,0x00000045,
+       0x0000008e,0x0004003d,0x00000007,0x00000091,0x00000090,0x0006000c,0x00000007,0x00000092,
+       0x00000001,0x00000045,0x00000091,0x0003003e,0x00000097,0x0000008f,0x0003003e,0x00000098,
+       0x00000092,0x0004003d,0x00000011,0x0000009a,0x00000094,0x0003003e,0x00000099,0x0000009a,
+       0x0004003d,0x00000009,0x0000009c,0x00000096,0x0003003e,0x0000009b,0x0000009c,0x00080039,
+       0x00000011,0x0000009d,0x00000018,0x00000097,0x00000098,0x00000099,0x0000009b,0x0003003e,
+       0x0000008b,0x0000009d,0x000100fd,0x00010038,0x00050036,0x00000002,0x0000000f,0x00000000,
+       0x0000000b,0x00030037,0x00000008,0x0000000c,0x00030037,0x00000008,0x0000000d,0x00030037,
+       0x0000000a,0x0000000e,0x000200f8,0x00000010,0x0004003b,0x00000008,0x0000001a,0x00000007,
+       0x0004003b,0x00000008,0x0000001e,0x00000007,0x0004003b,0x00000008,0x00000023,0x00000007,
+       0x0004003b,0x00000008,0x00000025,0x00000007,0x0004003b,0x0000002d,0x0000002e,0x00000007,
+       0x0004003b,0x0000002d,0x00000033,0x00000007,0x0004003b,0x0000002d,0x00000038,0x00000007,
+       0x0003003e,0x0000001a,0x0000001d,0x0004003d,0x00000007,0x0000001f,0x0000001a,0x0004003d,
+       0x00000007,0x00000020,0x0000000d,0x00050081,0x00000007,0x00000021,0x0000001f,0x00000020,
+       0x0006000c,0x00000007,0x00000022,0x00000001,0x00000045,0x00000021,0x0003003e,0x0000001e,
+       0x00000022,0x0004003d,0x00000009,0x00000024,0x0000000e,0x000300f7,0x00000027,0x00000000,
+       0x000400fa,0x00000024,0x00000026,0x00000029,0x000200f8,0x00000026,0x0004003d,0x00000007,
+       0x00000028,0x0000000c,0x0003003e,0x00000025,0x00000028,0x000200f9,0x00000027,0x000200f8,
+       0x00000029,0x0004003d,0x00000007,0x0000002a,0x0000000c,0x0004007f,0x00000007,0x0000002b,
+       0x0000002a,0x0003003e,0x00000025,0x0000002b,0x000200f9,0x00000027,0x000200f8,0x00000027,
+       0x0004003d,0x00000007,0x0000002c,0x00000025,0x0003003e,0x00000023,0x0000002c,0x0004003d,
+       0x00000007,0x0000002f,0x00000023,0x0004003d,0x00000007,0x00000030,0x0000001a,0x00050094,
+       0x00000006,0x00000031,0x0000002f,0x00000030,0x0007000c,0x00000006,0x00000032,0x00000001,
+       0x00000028,0x0000001b,0x00000031,0x0003003e,0x0000002e,0x00000032,0x0004003d,0x00000007,
+       0x00000034,0x00000023,0x0004003d,0x00000007,0x00000035,0x0000001e,0x00050094,0x00000006,
+       0x00000036,0x00000034,0x00000035,0x0007000c,0x00000006,0x00000037,0x00000001,0x00000028,
+       0x0000001b,0x00000036,0x0003003e,0x00000033,0x00000037,0x0003003e,0x00000038,0x0000001b,
+       0x0004003d,0x00000006,0x00000039,0x0000002e,0x000500ba,0x00000009,0x0000003a,0x00000039,
+       0x0000001b,0x000300f7,0x0000003c,0x00000000,0x000400fa,0x0000003a,0x0000003b,0x0000003c,
+       0x000200f8,0x0000003b,0x0004003d,0x00000006,0x0000003d,0x00000033,0x0007000c,0x00000006,
+       0x0000003f,0x00000001,0x0000001a,0x0000003d,0x0000003e,0x0003003e,0x00000038,0x0000003f,
+       0x000200f9,0x0000003c,0x000200f8,0x0000003c,0x0004003d,0x00000006,0x00000043,0x0000002e,
+       0x0005008e,0x00000007,0x00000044,0x00000042,0x00000043,0x0004003d,0x00000007,0x00000045,
+       0x00000041,0x00050081,0x00000007,0x00000046,0x00000045,0x00000044,0x0003003e,0x00000041,
+       0x00000046,0x0004003d,0x00000006,0x00000048,0x00000038,0x0005008e,0x00000007,0x00000049,
+       0x00000042,0x00000048,0x0004003d,0x00000007,0x0000004a,0x00000047,0x00050081,0x00000007,
+       0x0000004b,0x0000004a,0x00000049,0x0003003e,0x00000047,0x0000004b,0x000100fd,0x00010038,
+       0x00050036,0x00000011,0x00000018,0x00000000,0x00000013,0x00030037,0x00000008,0x00000014,
+       0x00030037,0x00000008,0x00000015,0x00030037,0x00000012,0x00000016,0x00030037,0x0000000a,
+       0x00000017,0x000200f8,0x00000019,0x0004003b,0x00000008,0x0000004e,0x00000007,0x0004003b,
+       0x00000008,0x00000057,0x00000007,0x0004003b,0x00000008,0x00000059,0x00000007,0x0004003b,
+       0x0000000a,0x0000005b,0x00000007,0x0004003b,0x00000012,0x0000005e,0x00000007,0x0004003b,
+       0x00000012,0x00000063,0x00000007,0x0004003b,0x00000012,0x00000068,0x00000007,0x0004003b,
+       0x00000012,0x0000006d,0x00000007,0x0004003b,0x00000008,0x0000006f,0x00000007,0x0003003e,
+       0x0000004c,0x00000042,0x0003003e,0x00000041,0x0000004d,0x0003003e,0x00000047,0x0000004d,
+       0x0004003d,0x00000011,0x0000004f,0x00000016,0x0008004f,0x00000007,0x00000050,0x0000004f,
+       0x0000004f,0x00000000,0x00000001,0x00000002,0x00050041,0x0000002d,0x00000053,0x00000016,
+       0x00000052,0x0004003d,0x00000006,0x00000054,0x00000053,0x00060050,0x00000007,0x00000055,
+       0x00000054,0x00000054,0x00000054,0x00050088,0x00000007,0x00000056,0x00000050,0x00000055,
+       0x0003003e,0x0000004e,0x00000056,0x0004003d,0x00000007,0x00000058,0x00000014,0x0003003e,
+       0x00000057,0x00000058,0x0004003d,0x00000007,0x0000005a,0x00000015,0x0003003e,0x00000059,
+       0x0000005a,0x0004003d,0x00000009,0x0000005c,0x00000017,0x0003003e,0x0000005b,0x0000005c,
+       0x00070039,0x00000002,0x0000005d,0x0000000f,0x00000057,0x00000059,0x0000005b,0x0003003e,
+       0x0000005e,0x00000062,0x0003003e,0x00000063,0x00000067,0x0003003e,0x00000068,0x0000006c,
+       0x0003003e,0x0000006d,0x0000006e,0x0004003d,0x00000007,0x00000070,0x0000004c,0x0004003d,
+       0x00000011,0x00000071,0x0000005e,0x0008004f,0x00000007,0x00000072,0x00000071,0x00000071,
+       0x00000000,0x00000001,0x00000002,0x00050085,0x00000007,0x00000073,0x00000070,0x00000072,
+       0x0004003d,0x00000007,0x00000074,0x00000041,0x0004003d,0x00000011,0x00000075,0x00000063,
+       0x0008004f,0x00000007,0x00000076,0x00000075,0x00000075,0x00000000,0x00000001,0x00000002,
+       0x00050085,0x00000007,0x00000077,0x00000074,0x00000076,0x00050081,0x00000007,0x00000078,
+       0x00000073,0x00000077,0x0004003d,0x00000007,0x00000079,0x00000047,0x0004003d,0x00000011,
+       0x0000007a,0x00000068,0x0008004f,0x00000007,0x0000007b,0x0000007a,0x0000007a,0x00000000,
+       0x00000001,0x00000002,0x00050085,0x00000007,0x0000007c,0x00000079,0x0000007b,0x00050081,
+       0x00000007,0x0000007d,0x00000078,0x0000007c,0x0004003d,0x00000011,0x0000007e,0x0000006d,
+       0x0008004f,0x00000007,0x0000007f,0x0000007e,0x0000007e,0x00000000,0x00000001,0x00000002,
+       0x00050081,0x00000007,0x00000080,0x0000007d,0x0000007f,0x0003003e,0x0000006f,0x00000080,
+       0x0004003d,0x00000007,0x00000081,0x0000006f,0x00050041,0x0000002d,0x00000082,0x00000063,
+       0x00000052,0x0004003d,0x00000006,0x00000083,0x00000082,0x00050051,0x00000006,0x00000084,
+       0x00000081,0x00000000,0x00050051,0x00000006,0x00000085,0x00000081,0x00000001,0x00050051,
+       0x00000006,0x00000086,0x00000081,0x00000002,0x00070050,0x00000011,0x00000087,0x00000084,
+       0x00000085,0x00000086,0x00000083,0x000200fe,0x00000087,0x00010038
+};
\ No newline at end of file
diff --git a/src/Vulkan/Vulkan_ShaderPhong_vs_spv.pxx b/src/Vulkan/Vulkan_ShaderPhong_vs_spv.pxx
new file mode 100644 (file)
index 0000000..33ee527
--- /dev/null
@@ -0,0 +1,91 @@
+       // 7.11.3113
+        #pragma once
+const uint32_t Vulkan_ShaderPhong_vs_spv[] = {
+       0x07230203,0x00010000,0x00080007,0x0000005b,0x00000000,0x00020011,0x00000001,0x0006000b,
+       0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+       0x000c000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000033,0x00000037,0x0000003a,
+       0x00000040,0x00000043,0x00000045,0x0000004e,0x00030003,0x00000002,0x000001c2,0x00040005,
+       0x00000004,0x6e69616d,0x00000000,0x00080005,0x0000000b,0x6e617274,0x726f6673,0x726f4e6d,
+       0x286c616d,0x3b336676,0x00000000,0x00050005,0x0000000a,0x4e656874,0x616d726f,0x0000006c,
+       0x000b0005,0x00000010,0x5763636f,0x646c726f,0x77656956,0x7274614d,0x6e497869,0x73726576,
+       0x61725465,0x6f70736e,0x00006573,0x00040005,0x00000011,0x6f6c6f43,0x00007372,0x00080006,
+       0x00000011,0x00000000,0x5763636f,0x646c726f,0x77656956,0x7274614d,0x00007869,0x00080006,
+       0x00000011,0x00000001,0x5063636f,0x656a6f72,0x6f697463,0x74614d6e,0x00786972,0x00080006,
+       0x00000011,0x00000002,0x4d63636f,0x6c65646f,0x6c726f57,0x74614d64,0x00786972,0x00050006,
+       0x00000011,0x00000003,0x6c6f4375,0x0000726f,0x00030005,0x00000013,0x00000000,0x000b0005,
+       0x0000001b,0x4d63636f,0x6c65646f,0x6c726f57,0x74614d64,0x49786972,0x7265766e,0x72546573,
+       0x70736e61,0x0065736f,0x00040005,0x00000022,0x73655261,0x00746c75,0x00060005,0x00000033,
+       0x69736f50,0x6e6f6974,0x6c726f57,0x00000064,0x00050005,0x00000037,0x5663636f,0x65747265,
+       0x00000078,0x00050005,0x0000003a,0x69736f50,0x6e6f6974,0x00000000,0x00040005,0x00000040,
+       0x77656956,0x00000000,0x00040005,0x00000043,0x6d726f4e,0x00006c61,0x00050005,0x00000045,
+       0x4e63636f,0x616d726f,0x0000006c,0x00040005,0x00000046,0x61726170,0x0000006d,0x00060005,
+       0x0000004c,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x0000004c,0x00000000,
+       0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x0000004c,0x00000001,0x505f6c67,0x746e696f,
+       0x657a6953,0x00000000,0x00070006,0x0000004c,0x00000002,0x435f6c67,0x4470696c,0x61747369,
+       0x0065636e,0x00070006,0x0000004c,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,
+       0x00030005,0x0000004e,0x00000000,0x00040048,0x00000011,0x00000000,0x00000005,0x00050048,
+       0x00000011,0x00000000,0x00000023,0x00000000,0x00050048,0x00000011,0x00000000,0x00000007,
+       0x00000010,0x00040048,0x00000011,0x00000001,0x00000005,0x00050048,0x00000011,0x00000001,
+       0x00000023,0x00000040,0x00050048,0x00000011,0x00000001,0x00000007,0x00000010,0x00040048,
+       0x00000011,0x00000002,0x00000005,0x00050048,0x00000011,0x00000002,0x00000023,0x00000080,
+       0x00050048,0x00000011,0x00000002,0x00000007,0x00000010,0x00050048,0x00000011,0x00000003,
+       0x00000023,0x000000c0,0x00030047,0x00000011,0x00000002,0x00040047,0x00000013,0x00000022,
+       0x00000000,0x00040047,0x00000013,0x00000021,0x00000000,0x00040047,0x00000033,0x0000001e,
+       0x00000001,0x00040047,0x00000037,0x0000001e,0x00000000,0x00040047,0x0000003a,0x0000001e,
+       0x00000002,0x00040047,0x00000040,0x0000001e,0x00000003,0x00040047,0x00000043,0x0000001e,
+       0x00000000,0x00040047,0x00000045,0x0000001e,0x00000001,0x00050048,0x0000004c,0x00000000,
+       0x0000000b,0x00000000,0x00050048,0x0000004c,0x00000001,0x0000000b,0x00000001,0x00050048,
+       0x0000004c,0x00000002,0x0000000b,0x00000003,0x00050048,0x0000004c,0x00000003,0x0000000b,
+       0x00000004,0x00030047,0x0000004c,0x00000002,0x00020013,0x00000002,0x00030021,0x00000003,
+       0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000003,
+       0x00040020,0x00000008,0x00000007,0x00000007,0x00040021,0x00000009,0x00000007,0x00000008,
+       0x00040017,0x0000000d,0x00000006,0x00000004,0x00040018,0x0000000e,0x0000000d,0x00000004,
+       0x00040020,0x0000000f,0x00000007,0x0000000e,0x0006001e,0x00000011,0x0000000e,0x0000000e,
+       0x0000000e,0x0000000d,0x00040020,0x00000012,0x00000002,0x00000011,0x0004003b,0x00000012,
+       0x00000013,0x00000002,0x00040015,0x00000014,0x00000020,0x00000001,0x0004002b,0x00000014,
+       0x00000015,0x00000000,0x00040020,0x00000016,0x00000002,0x0000000e,0x0004002b,0x00000014,
+       0x0000001c,0x00000002,0x00040020,0x00000021,0x00000007,0x0000000d,0x0004002b,0x00000006,
+       0x00000027,0x00000000,0x00040020,0x00000032,0x00000003,0x0000000d,0x0004003b,0x00000032,
+       0x00000033,0x00000003,0x00040020,0x00000036,0x00000001,0x0000000d,0x0004003b,0x00000036,
+       0x00000037,0x00000001,0x0004003b,0x00000032,0x0000003a,0x00000003,0x00040020,0x0000003f,
+       0x00000003,0x00000007,0x0004003b,0x0000003f,0x00000040,0x00000003,0x0004002b,0x00000006,
+       0x00000041,0x3f800000,0x0006002c,0x00000007,0x00000042,0x00000027,0x00000027,0x00000041,
+       0x0004003b,0x0000003f,0x00000043,0x00000003,0x00040020,0x00000044,0x00000001,0x00000007,
+       0x0004003b,0x00000044,0x00000045,0x00000001,0x00040015,0x00000049,0x00000020,0x00000000,
+       0x0004002b,0x00000049,0x0000004a,0x00000001,0x0004001c,0x0000004b,0x00000006,0x0000004a,
+       0x0006001e,0x0000004c,0x0000000d,0x00000006,0x0000004b,0x0000004b,0x00040020,0x0000004d,
+       0x00000003,0x0000004c,0x0004003b,0x0000004d,0x0000004e,0x00000003,0x0004002b,0x00000014,
+       0x0000004f,0x00000001,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,
+       0x00000005,0x0004003b,0x00000008,0x00000046,0x00000007,0x00050041,0x00000016,0x00000034,
+       0x00000013,0x0000001c,0x0004003d,0x0000000e,0x00000035,0x00000034,0x0004003d,0x0000000d,
+       0x00000038,0x00000037,0x00050091,0x0000000d,0x00000039,0x00000035,0x00000038,0x0003003e,
+       0x00000033,0x00000039,0x00050041,0x00000016,0x0000003b,0x00000013,0x00000015,0x0004003d,
+       0x0000000e,0x0000003c,0x0000003b,0x0004003d,0x0000000d,0x0000003d,0x00000033,0x00050091,
+       0x0000000d,0x0000003e,0x0000003c,0x0000003d,0x0003003e,0x0000003a,0x0000003e,0x0003003e,
+       0x00000040,0x00000042,0x0004003d,0x00000007,0x00000047,0x00000045,0x0003003e,0x00000046,
+       0x00000047,0x00050039,0x00000007,0x00000048,0x0000000b,0x00000046,0x0003003e,0x00000043,
+       0x00000048,0x00050041,0x00000016,0x00000050,0x00000013,0x0000004f,0x0004003d,0x0000000e,
+       0x00000051,0x00000050,0x00050041,0x00000016,0x00000052,0x00000013,0x00000015,0x0004003d,
+       0x0000000e,0x00000053,0x00000052,0x00050092,0x0000000e,0x00000054,0x00000051,0x00000053,
+       0x00050041,0x00000016,0x00000055,0x00000013,0x0000001c,0x0004003d,0x0000000e,0x00000056,
+       0x00000055,0x00050092,0x0000000e,0x00000057,0x00000054,0x00000056,0x0004003d,0x0000000d,
+       0x00000058,0x00000037,0x00050091,0x0000000d,0x00000059,0x00000057,0x00000058,0x00050041,
+       0x00000032,0x0000005a,0x0000004e,0x00000015,0x0003003e,0x0000005a,0x00000059,0x000100fd,
+       0x00010038,0x00050036,0x00000007,0x0000000b,0x00000000,0x00000009,0x00030037,0x00000008,
+       0x0000000a,0x000200f8,0x0000000c,0x0004003b,0x0000000f,0x00000010,0x00000007,0x0004003b,
+       0x0000000f,0x0000001b,0x00000007,0x0004003b,0x00000021,0x00000022,0x00000007,0x00050041,
+       0x00000016,0x00000017,0x00000013,0x00000015,0x0004003d,0x0000000e,0x00000018,0x00000017,
+       0x0006000c,0x0000000e,0x00000019,0x00000001,0x00000022,0x00000018,0x00040054,0x0000000e,
+       0x0000001a,0x00000019,0x0003003e,0x00000010,0x0000001a,0x00050041,0x00000016,0x0000001d,
+       0x00000013,0x0000001c,0x0004003d,0x0000000e,0x0000001e,0x0000001d,0x0006000c,0x0000000e,
+       0x0000001f,0x00000001,0x00000022,0x0000001e,0x00040054,0x0000000e,0x00000020,0x0000001f,
+       0x0003003e,0x0000001b,0x00000020,0x0004003d,0x0000000e,0x00000023,0x00000010,0x0004003d,
+       0x0000000e,0x00000024,0x0000001b,0x00050092,0x0000000e,0x00000025,0x00000023,0x00000024,
+       0x0004003d,0x00000007,0x00000026,0x0000000a,0x00050051,0x00000006,0x00000028,0x00000026,
+       0x00000000,0x00050051,0x00000006,0x00000029,0x00000026,0x00000001,0x00050051,0x00000006,
+       0x0000002a,0x00000026,0x00000002,0x00070050,0x0000000d,0x0000002b,0x00000028,0x00000029,
+       0x0000002a,0x00000027,0x00050091,0x0000000d,0x0000002c,0x00000025,0x0000002b,0x0003003e,
+       0x00000022,0x0000002c,0x0004003d,0x0000000d,0x0000002d,0x00000022,0x0008004f,0x00000007,
+       0x0000002e,0x0000002d,0x0000002d,0x00000000,0x00000001,0x00000002,0x0006000c,0x00000007,
+       0x0000002f,0x00000001,0x00000045,0x0000002e,0x000200fe,0x0000002f,0x00010038
+};
\ No newline at end of file
diff --git a/src/Vulkan/Vulkan_ShaderUnlit.fs b/src/Vulkan/Vulkan_ShaderUnlit.fs
new file mode 100644 (file)
index 0000000..1f0af10
--- /dev/null
@@ -0,0 +1,16 @@
+#version 450
+
+layout(std140, binding=0) uniform Colors
+{
+  mat4 occWorldViewMatrix;  //!< World-view  matrix
+  mat4 occProjectionMatrix; //!< Projection  matrix
+  mat4 occModelWorldMatrix; //!< Model-world matrix
+  vec4 uColor;
+};
+
+layout(location = 0) out vec4 occFragColor0;
+
+void main()
+{
+  occFragColor0 = uColor;
+}
diff --git a/src/Vulkan/Vulkan_ShaderUnlit.vs b/src/Vulkan/Vulkan_ShaderUnlit.vs
new file mode 100644 (file)
index 0000000..cb48281
--- /dev/null
@@ -0,0 +1,16 @@
+#version 450
+
+layout(std140, binding=0) uniform Colors
+{
+  mat4 occWorldViewMatrix;  //!< World-view  matrix
+  mat4 occProjectionMatrix; //!< Projection  matrix
+  mat4 occModelWorldMatrix; //!< Model-world matrix
+  vec4 uColor;
+};
+
+layout(location = 0) in vec4 occVertex;
+
+void main()
+{
+  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;
+}
diff --git a/src/Vulkan/Vulkan_ShaderUnlit_fs_spv.pxx b/src/Vulkan/Vulkan_ShaderUnlit_fs_spv.pxx
new file mode 100644 (file)
index 0000000..02f87e3
--- /dev/null
@@ -0,0 +1,30 @@
+       // 7.11.3113
+        #pragma once
+const uint32_t Vulkan_ShaderUnlit_fs_spv[] = {
+       0x07230203,0x00010000,0x00080007,0x00000013,0x00000000,0x00020011,0x00000001,0x0006000b,
+       0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+       0x0006000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x00030010,0x00000004,
+       0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,
+       0x00060005,0x00000009,0x4663636f,0x43676172,0x726f6c6f,0x00000030,0x00040005,0x0000000b,
+       0x6f6c6f43,0x00007372,0x00080006,0x0000000b,0x00000000,0x5763636f,0x646c726f,0x77656956,
+       0x7274614d,0x00007869,0x00080006,0x0000000b,0x00000001,0x5063636f,0x656a6f72,0x6f697463,
+       0x74614d6e,0x00786972,0x00080006,0x0000000b,0x00000002,0x4d63636f,0x6c65646f,0x6c726f57,
+       0x74614d64,0x00786972,0x00050006,0x0000000b,0x00000003,0x6c6f4375,0x0000726f,0x00030005,
+       0x0000000d,0x00000000,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040048,0x0000000b,
+       0x00000000,0x00000005,0x00050048,0x0000000b,0x00000000,0x00000023,0x00000000,0x00050048,
+       0x0000000b,0x00000000,0x00000007,0x00000010,0x00040048,0x0000000b,0x00000001,0x00000005,
+       0x00050048,0x0000000b,0x00000001,0x00000023,0x00000040,0x00050048,0x0000000b,0x00000001,
+       0x00000007,0x00000010,0x00040048,0x0000000b,0x00000002,0x00000005,0x00050048,0x0000000b,
+       0x00000002,0x00000023,0x00000080,0x00050048,0x0000000b,0x00000002,0x00000007,0x00000010,
+       0x00050048,0x0000000b,0x00000003,0x00000023,0x000000c0,0x00030047,0x0000000b,0x00000002,
+       0x00040047,0x0000000d,0x00000022,0x00000000,0x00040047,0x0000000d,0x00000021,0x00000000,
+       0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,
+       0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,0x00000003,0x00000007,
+       0x0004003b,0x00000008,0x00000009,0x00000003,0x00040018,0x0000000a,0x00000007,0x00000004,
+       0x0006001e,0x0000000b,0x0000000a,0x0000000a,0x0000000a,0x00000007,0x00040020,0x0000000c,
+       0x00000002,0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000002,0x00040015,0x0000000e,
+       0x00000020,0x00000001,0x0004002b,0x0000000e,0x0000000f,0x00000003,0x00040020,0x00000010,
+       0x00000002,0x00000007,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,
+       0x00000005,0x00050041,0x00000010,0x00000011,0x0000000d,0x0000000f,0x0004003d,0x00000007,
+       0x00000012,0x00000011,0x0003003e,0x00000009,0x00000012,0x000100fd,0x00010038
+};
\ No newline at end of file
diff --git a/src/Vulkan/Vulkan_ShaderUnlit_vs_spv.pxx b/src/Vulkan/Vulkan_ShaderUnlit_vs_spv.pxx
new file mode 100644 (file)
index 0000000..56d8a61
--- /dev/null
@@ -0,0 +1,47 @@
+       // 7.11.3113
+        #pragma once
+const uint32_t Vulkan_ShaderUnlit_vs_spv[] = {
+       0x07230203,0x00010000,0x00080007,0x00000025,0x00000000,0x00020011,0x00000001,0x0006000b,
+       0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+       0x0007000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000d,0x00000020,0x00030003,
+       0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,0x0000000b,
+       0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x0000000b,0x00000000,0x505f6c67,
+       0x7469736f,0x006e6f69,0x00070006,0x0000000b,0x00000001,0x505f6c67,0x746e696f,0x657a6953,
+       0x00000000,0x00070006,0x0000000b,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,
+       0x00070006,0x0000000b,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,
+       0x0000000d,0x00000000,0x00040005,0x00000011,0x6f6c6f43,0x00007372,0x00080006,0x00000011,
+       0x00000000,0x5763636f,0x646c726f,0x77656956,0x7274614d,0x00007869,0x00080006,0x00000011,
+       0x00000001,0x5063636f,0x656a6f72,0x6f697463,0x74614d6e,0x00786972,0x00080006,0x00000011,
+       0x00000002,0x4d63636f,0x6c65646f,0x6c726f57,0x74614d64,0x00786972,0x00050006,0x00000011,
+       0x00000003,0x6c6f4375,0x0000726f,0x00030005,0x00000013,0x00000000,0x00050005,0x00000020,
+       0x5663636f,0x65747265,0x00000078,0x00050048,0x0000000b,0x00000000,0x0000000b,0x00000000,
+       0x00050048,0x0000000b,0x00000001,0x0000000b,0x00000001,0x00050048,0x0000000b,0x00000002,
+       0x0000000b,0x00000003,0x00050048,0x0000000b,0x00000003,0x0000000b,0x00000004,0x00030047,
+       0x0000000b,0x00000002,0x00040048,0x00000011,0x00000000,0x00000005,0x00050048,0x00000011,
+       0x00000000,0x00000023,0x00000000,0x00050048,0x00000011,0x00000000,0x00000007,0x00000010,
+       0x00040048,0x00000011,0x00000001,0x00000005,0x00050048,0x00000011,0x00000001,0x00000023,
+       0x00000040,0x00050048,0x00000011,0x00000001,0x00000007,0x00000010,0x00040048,0x00000011,
+       0x00000002,0x00000005,0x00050048,0x00000011,0x00000002,0x00000023,0x00000080,0x00050048,
+       0x00000011,0x00000002,0x00000007,0x00000010,0x00050048,0x00000011,0x00000003,0x00000023,
+       0x000000c0,0x00030047,0x00000011,0x00000002,0x00040047,0x00000013,0x00000022,0x00000000,
+       0x00040047,0x00000013,0x00000021,0x00000000,0x00040047,0x00000020,0x0000001e,0x00000000,
+       0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,
+       0x00040017,0x00000007,0x00000006,0x00000004,0x00040015,0x00000008,0x00000020,0x00000000,
+       0x0004002b,0x00000008,0x00000009,0x00000001,0x0004001c,0x0000000a,0x00000006,0x00000009,
+       0x0006001e,0x0000000b,0x00000007,0x00000006,0x0000000a,0x0000000a,0x00040020,0x0000000c,
+       0x00000003,0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000003,0x00040015,0x0000000e,
+       0x00000020,0x00000001,0x0004002b,0x0000000e,0x0000000f,0x00000000,0x00040018,0x00000010,
+       0x00000007,0x00000004,0x0006001e,0x00000011,0x00000010,0x00000010,0x00000010,0x00000007,
+       0x00040020,0x00000012,0x00000002,0x00000011,0x0004003b,0x00000012,0x00000013,0x00000002,
+       0x0004002b,0x0000000e,0x00000014,0x00000001,0x00040020,0x00000015,0x00000002,0x00000010,
+       0x0004002b,0x0000000e,0x0000001b,0x00000002,0x00040020,0x0000001f,0x00000001,0x00000007,
+       0x0004003b,0x0000001f,0x00000020,0x00000001,0x00040020,0x00000023,0x00000003,0x00000007,
+       0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041,
+       0x00000015,0x00000016,0x00000013,0x00000014,0x0004003d,0x00000010,0x00000017,0x00000016,
+       0x00050041,0x00000015,0x00000018,0x00000013,0x0000000f,0x0004003d,0x00000010,0x00000019,
+       0x00000018,0x00050092,0x00000010,0x0000001a,0x00000017,0x00000019,0x00050041,0x00000015,
+       0x0000001c,0x00000013,0x0000001b,0x0004003d,0x00000010,0x0000001d,0x0000001c,0x00050092,
+       0x00000010,0x0000001e,0x0000001a,0x0000001d,0x0004003d,0x00000007,0x00000021,0x00000020,
+       0x00050091,0x00000007,0x00000022,0x0000001e,0x00000021,0x00050041,0x00000023,0x00000024,
+       0x0000000d,0x0000000f,0x0003003e,0x00000024,0x00000022,0x000100fd,0x00010038
+};
\ No newline at end of file
diff --git a/src/Vulkan/Vulkan_Structure.cxx b/src/Vulkan/Vulkan_Structure.cxx
new file mode 100644 (file)
index 0000000..137d7f3
--- /dev/null
@@ -0,0 +1,469 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_Structure.hxx>
+
+#include <Vulkan_Context.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_GraphicDriver.hxx>
+#include <Vulkan_Group.hxx>
+#include <Vulkan_StructureShadow.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Structure, Graphic3d_CStructure)
+
+// =======================================================================
+// function : Vulkan_Structure
+// purpose  :
+// =======================================================================
+Vulkan_Structure::Vulkan_Structure (const Handle(Graphic3d_StructureManager)& theManager)
+: Graphic3d_CStructure (theManager),
+  myInstancedStructure (NULL),
+  myIsMirrored         (Standard_False)
+{
+  updateLayerTransformation();
+}
+
+// =======================================================================
+// function : ~Vulkan_Structure
+// purpose  :
+// =======================================================================
+Vulkan_Structure::~Vulkan_Structure()
+{
+  /// TODO
+  ///Release (Handle(OpenGl_Context)());
+}
+
+// =======================================================================
+// function : SetZLayer
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerIndex)
+{
+  Graphic3d_CStructure::SetZLayer (theLayerIndex);
+  updateLayerTransformation();
+}
+
+// =======================================================================
+// function : SetTransformation
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::SetTransformation (const Handle(Geom_Transformation)& theTrsf)
+{
+  myTrsf = theTrsf;
+  myIsMirrored = Standard_False;
+  if (!myTrsf.IsNull())
+  {
+    // Determinant of transform matrix less then 0 means that mirror transform applied.
+    const Standard_Real aDet = myTrsf->Value(1, 1) * (myTrsf->Value (2, 2) * myTrsf->Value (3, 3) - myTrsf->Value (3, 2) * myTrsf->Value (2, 3))
+                             - myTrsf->Value(1, 2) * (myTrsf->Value (2, 1) * myTrsf->Value (3, 3) - myTrsf->Value (3, 1) * myTrsf->Value (2, 3))
+                             + myTrsf->Value(1, 3) * (myTrsf->Value (2, 1) * myTrsf->Value (3, 2) - myTrsf->Value (3, 1) * myTrsf->Value (2, 2));
+    myIsMirrored = aDet < 0.0;
+  }
+
+  updateLayerTransformation();
+}
+
+// =======================================================================
+// function : SetTransformPersistence
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
+{
+  myTrsfPers = theTrsfPers;
+  updateLayerTransformation();
+}
+
+// =======================================================================
+// function : updateLayerTransformation
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::updateLayerTransformation()
+{
+  gp_Trsf aRenderTrsf;
+  if (!myTrsf.IsNull())
+  {
+    aRenderTrsf = myTrsf->Trsf();
+  }
+
+  const Graphic3d_ZLayerSettings& aLayer = myGraphicDriver->ZLayerSettings (myZLayer);
+  if (!aLayer.OriginTransformation().IsNull()
+    && myTrsfPers.IsNull())
+  {
+    aRenderTrsf.SetTranslationPart (aRenderTrsf.TranslationPart() - aLayer.Origin());
+  }
+  aRenderTrsf.GetMat4 (myRenderTrsf);
+}
+
+// =======================================================================
+// function : GraphicHighlight
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::GraphicHighlight (const Handle(Graphic3d_PresentationAttributes)& theStyle)
+{
+  myHighlightStyle = theStyle;
+  highlight = 1;
+}
+
+// =======================================================================
+// function : GraphicUnhighlight
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::GraphicUnhighlight()
+{
+  highlight = 0;
+  myHighlightStyle.Nullify();
+}
+
+// =======================================================================
+// function : OnVisibilityChanged
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::OnVisibilityChanged()
+{
+  //
+}
+
+// =======================================================================
+// function : Connect
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::Connect (Graphic3d_CStructure& theStructure)
+{
+  Vulkan_Structure* aStruct = static_cast<Vulkan_Structure*> (&theStructure);
+  Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct,
+                         "Error! Instanced structure is already defined");
+  myInstancedStructure = aStruct;
+}
+
+// =======================================================================
+// function : Disconnect
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::Disconnect (Graphic3d_CStructure& theStructure)
+{
+  Vulkan_Structure* aStruct = static_cast<Vulkan_Structure*> (&theStructure);
+  if (myInstancedStructure == aStruct)
+  {
+    myInstancedStructure = NULL;
+  }
+}
+
+// =======================================================================
+// function : NewGroup
+// purpose  :
+// =======================================================================
+Handle(Graphic3d_Group) Vulkan_Structure::NewGroup (const Handle(Graphic3d_Structure)& theStruct)
+{
+  Handle(Vulkan_Group) aGroup = new Vulkan_Group (theStruct);
+  myGroups.Append (aGroup);
+  return aGroup;
+}
+
+// =======================================================================
+// function : RemoveGroup
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup)
+{
+  if (theGroup.IsNull())
+  {
+    return;
+  }
+
+  for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
+  {
+    // Check for the given group
+    if (aGroupIter.Value() == theGroup)
+    {
+      theGroup->Clear (Standard_False);
+      myGroups.Remove (aGroupIter);
+      return;
+    }
+  }
+}
+
+// =======================================================================
+// function : Clear
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::Clear()
+{
+  myGroups.Clear();
+  ///Clear (VkDriver()->GetSharedContext());
+}
+
+// =======================================================================
+// function : Clear
+// purpose  :
+// =======================================================================
+/*void Vulkan_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
+{
+  Standard_Boolean aRaytracableGroupDeleted (Standard_False);
+
+  // Release groups
+  for (Vulkan_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
+  {
+    aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable();
+
+    // Delete objects
+    aGroupIter.ChangeValue()->Release (theGlCtx);
+  }
+  myGroups.Clear();
+
+  if (aRaytracableGroupDeleted)
+  {
+    myIsRaytracable = Standard_False;
+  }
+
+  Is2dText       = Standard_False;
+  IsForHighlight = Standard_False;
+}*/
+
+// =======================================================================
+// function : renderGeometry
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::renderGeometry (const Handle(Vulkan_Context)& theCtx,
+                                       bool& theHasClosed) const
+{
+  if (myInstancedStructure != NULL)
+  {
+    myInstancedStructure->renderGeometry (theCtx, theHasClosed);
+  }
+
+  for (Vulkan_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
+  {
+    theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed();
+    aGroupIter.Value()->Render (theCtx);
+  }
+}
+
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
+void Vulkan_Structure::Render (const Handle(Vulkan_Context)& theCtx) const
+{
+  // Process the structure only if visible
+  if (!visible)
+  {
+    return;
+  }
+
+  /*const Handle(Vulkan_Device)& aDevice = theCtx->Device();
+
+  // Render named status
+  if (highlight && !myHighlightStyle.IsNull() && myHighlightStyle->Method() != Aspect_TOHM_BOUNDBOX)
+  {
+    theWorkspace->SetHighlightStyle (myHighlightStyle);
+  }
+
+  // Apply local transformation
+  aCtx->ModelWorldState.Push();
+  OpenGl_Mat4& aModelWorld = aCtx->ModelWorldState.ChangeCurrent();
+  aModelWorld = myRenderTrsf;
+
+  const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
+  if (!myTrsfPers.IsNull())
+  {
+    aCtx->WorldViewState.Push();
+    OpenGl_Mat4& aWorldView = aCtx->WorldViewState.ChangeCurrent();
+    myTrsfPers->Apply (theWorkspace->View()->Camera(),
+                       aCtx->ProjectionState.Current(), aWorldView,
+                       aCtx->VirtualViewport()[2], aCtx->VirtualViewport()[3]);
+  }
+
+  // Take into account transform persistence
+  aCtx->ApplyModelViewMatrix();
+
+  // remember aspects
+  const OpenGl_Aspects* aPrevAspectFace = theWorkspace->Aspects();
+
+  // Apply correction for mirror transform
+  if (myIsMirrored)
+  {
+    aCtx->core11fwd->glFrontFace (GL_CW);
+  }
+
+  // Collect clipping planes of structure scope
+  aCtx->ChangeClipping().SetLocalPlanes (myClipPlanes);*/
+
+  // True if structure is fully clipped
+  bool isClipped = false;
+  /*bool hasDisabled = false;
+  if (aCtx->Clipping().IsClippingOrCappingOn())
+  {
+    const Graphic3d_BndBox3d& aBBox = BoundingBox();
+    if (!myClipPlanes.IsNull()
+      && myClipPlanes->ToOverrideGlobal())
+    {
+      aCtx->ChangeClipping().DisableGlobal();
+      hasDisabled = aCtx->Clipping().HasDisabled();
+    }
+    else if (!myTrsfPers.IsNull())
+    {
+      if (myTrsfPers->IsZoomOrRotate())
+      {
+        // Zoom/rotate persistence object lives in two worlds at the same time.
+        // Global clipping planes can not be trivially applied without being converted
+        // into local space of transformation persistence object.
+        // As more simple alternative - just clip entire object by its anchor point defined in the world space.
+        const gp_Pnt anAnchor = myTrsfPers->AnchorPoint();
+        for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More() && aPlaneIt.IsGlobal(); aPlaneIt.Next())
+        {
+          const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+          if (!aPlane->IsOn())
+          {
+            continue;
+          }
+
+          // check for clipping
+          const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
+          if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
+          {
+            isClipped = true;
+            break;
+          }
+        }
+      }
+
+      aCtx->ChangeClipping().DisableGlobal();
+      hasDisabled = aCtx->Clipping().HasDisabled();
+    }
+
+    // Set of clipping planes that do not intersect the structure,
+    // and thus can be disabled to improve rendering performance
+    if (aBBox.IsValid()
+     && myTrsfPers.IsNull())
+    {
+      for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More(); aPlaneIt.Next())
+      {
+        const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+        if (aPlaneIt.IsDisabled())
+        {
+          continue;
+        }
+
+        const Graphic3d_ClipState aBoxState = aPlane->ProbeBox (aBBox);
+        if (aBoxState == Graphic3d_ClipState_Out)
+        {
+          isClipped = true;
+          break;
+        }
+        else if (aBoxState == Graphic3d_ClipState_In)
+        {
+          aCtx->ChangeClipping().SetEnabled (aPlaneIt, false);
+          hasDisabled = true;
+        }
+      }
+    }
+
+    if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
+     || hasDisabled)
+    {
+      // Set OCCT state uniform variables
+      aCtx->ShaderManager()->UpdateClippingState();
+    }
+  }*/
+
+  // Render groups
+  bool hasClosedPrims = false;
+  if (!isClipped)
+  {
+    renderGeometry (theCtx, hasClosedPrims);
+  }
+
+  // Reset correction for mirror transform
+  /*if (myIsMirrored)
+  {
+    aCtx->core11fwd->glFrontFace (GL_CCW);
+  }
+
+  // Render capping for structure groups
+  if (hasClosedPrims
+   && aCtx->Clipping().IsCappingOn())
+  {
+    OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this);
+  }
+
+  // Revert structure clippings
+  if (hasDisabled)
+  {
+    // enable planes that were previously disabled
+    aCtx->ChangeClipping().RestoreDisabled();
+  }
+  aCtx->ChangeClipping().SetLocalPlanes (Handle(Graphic3d_SequenceOfHClipPlane)());
+  if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
+    || hasDisabled)
+  {
+    // Set OCCT state uniform variables
+    aCtx->ShaderManager()->RevertClippingState();
+  }
+
+  // Restore local transformation
+  aCtx->ModelWorldState.Pop();
+  aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
+
+  // Restore aspects
+  theWorkspace->SetAspects (aPrevAspectFace);
+
+  // Apply highlight box
+  if (!isClipped
+   && !myHighlightStyle.IsNull()
+   &&  myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX)
+  {
+    aCtx->ApplyModelViewMatrix();
+    theWorkspace->SetHighlightStyle (myHighlightStyle);
+    renderBoundingBox (theWorkspace);
+  }
+
+  if (!myTrsfPers.IsNull())
+  {
+    aCtx->WorldViewState.Pop();
+  }
+
+  // Restore named status
+  theWorkspace->SetHighlightStyle (Handle(Graphic3d_PresentationAttributes)());*/
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+/*void Vulkan_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
+{
+  // Release groups
+  Clear (theGlCtx);
+  myHighlightStyle.Nullify();
+}*/
+
+// =======================================================================
+// function : ReleaseGlResources
+// purpose  :
+// =======================================================================
+/*void Vulkan_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
+{
+  for (Vulkan_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
+  {
+    aGroupIter.ChangeValue()->Release (theGlCtx);
+  }
+}*/
+
+//=======================================================================
+//function : ShadowLink
+//purpose  :
+//=======================================================================
+Handle(Graphic3d_CStructure) Vulkan_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const
+{
+  return new Vulkan_StructureShadow (theManager, this);
+}
diff --git a/src/Vulkan/Vulkan_Structure.hxx b/src/Vulkan/Vulkan_Structure.hxx
new file mode 100644 (file)
index 0000000..7c4b1e2
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Structure_HeaderFile
+#define _Vulkan_Structure_HeaderFile
+
+#include <Graphic3d_CStructure.hxx>
+
+class Vulkan_Context;
+
+//! Implementation of low-level graphic structure.
+class Vulkan_Structure : public Graphic3d_CStructure
+{
+  friend class Vulkan_Group;
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Structure, Graphic3d_CStructure)
+public:
+
+  //! Auxiliary wrapper to iterate OpenGl_Structure sequence.
+  typedef SubclassStructIterator<Vulkan_Structure> StructIterator;
+
+  //! Auxiliary wrapper to iterate OpenGl_Group sequence.
+  typedef SubclassGroupIterator<Vulkan_Group> GroupIterator;
+
+public:
+
+  //! Create empty structure
+  Standard_EXPORT Vulkan_Structure (const Handle(Graphic3d_StructureManager)& theManager);
+
+  //! Setup structure graphic state
+  Standard_EXPORT virtual void OnVisibilityChanged() Standard_OVERRIDE;
+
+  //! Clear graphic data
+  Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+
+  //! Connect other structure to this one
+  Standard_EXPORT virtual void Connect    (Graphic3d_CStructure& theStructure) Standard_OVERRIDE;
+
+  //! Disconnect other structure to this one
+  Standard_EXPORT virtual void Disconnect (Graphic3d_CStructure& theStructure) Standard_OVERRIDE;
+
+  //! Synchronize structure transformation
+  Standard_EXPORT virtual void SetTransformation (const Handle(Geom_Transformation)& theTrsf) Standard_OVERRIDE;
+
+  //! Set transformation persistence.
+  Standard_EXPORT virtual void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) Standard_OVERRIDE;
+
+  //! Set z layer ID to display the structure in specified layer
+  Standard_EXPORT virtual void SetZLayer(const Graphic3d_ZLayerId theLayerIndex) Standard_OVERRIDE;
+
+  //! Highlights structure according to the given style and updates corresponding class fields
+  //! (highlight status and style)
+  Standard_EXPORT virtual void GraphicHighlight (const Handle(Graphic3d_PresentationAttributes)& theStyle) Standard_OVERRIDE;
+
+  //! Unighlights structure and updates corresponding class fields (highlight status and style)
+  Standard_EXPORT virtual void GraphicUnhighlight() Standard_OVERRIDE;
+
+  //! Create shadow link to this structure
+  Standard_EXPORT virtual Handle(Graphic3d_CStructure) ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const Standard_OVERRIDE;
+
+  //! Create new group within this structure
+  Standard_EXPORT virtual Handle(Graphic3d_Group) NewGroup (const Handle(Graphic3d_Structure)& theStruct) Standard_OVERRIDE;
+
+  //! Remove group from this structure
+  Standard_EXPORT virtual void RemoveGroup (const Handle(Graphic3d_Group)& theGroup) Standard_OVERRIDE;
+
+public:
+
+  //! Access graphic driver
+  /**Vulkan_GraphicDriver* VkDriver() const
+  {
+    return (Vulkan_GraphicDriver* )myGraphicDriver.get();
+  }
+
+  Standard_EXPORT void Clear (const Handle(OpenGl_Context)& theGlCtx);*/
+
+  //! Renders the structure.
+  virtual void Render (const Handle(Vulkan_Context)& theCtx) const;
+
+  //! Releases structure resources.
+  /*virtual void Release (const Handle(OpenGl_Context)& theGlCtx);
+
+  //! This method releases GL resources without actual elements destruction.
+  //! As result structure could be correctly destroyed layer without GL context
+  //! (after last window was closed for example).
+  //!
+  //! Notice however that reusage of this structure after calling this method is incorrect
+  //! and will lead to broken visualization due to loosed data.
+  Standard_EXPORT void ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx);*/
+
+  //! Returns instanced OpenGL structure.
+  const Vulkan_Structure* InstancedStructure() const { return myInstancedStructure; }
+
+  //! Update render transformation matrix.
+  Standard_EXPORT virtual void updateLayerTransformation() Standard_OVERRIDE;
+
+protected:
+
+  Standard_EXPORT virtual ~Vulkan_Structure();
+
+  //! Renders groups of structure without applying any attributes (i.e. transform, material etc).
+  //! @param theWorkspace current workspace
+  //! @param theHasClosed flag will be set to TRUE if structure contains at least one group of closed primitives
+  Standard_EXPORT void renderGeometry (const Handle(Vulkan_Context)& theCtx,
+                                       bool& theHasClosed) const;
+
+protected:
+
+  Vulkan_Structure* myInstancedStructure;
+  Graphic3d_Mat4    myRenderTrsf; //!< transformation, actually used for rendering (includes Local Origin shift)
+  Standard_Boolean  myIsMirrored; //!< Used to tell OpenGl to interpret polygons in clockwise order.
+
+};
+
+#endif // _Vulkan_Structure_HeaderFile
diff --git a/src/Vulkan/Vulkan_StructureShadow.cxx b/src/Vulkan/Vulkan_StructureShadow.cxx
new file mode 100644 (file)
index 0000000..b98915f
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_StructureShadow.hxx>
+
+#include <Graphic3d_GraphicDriver.hxx>
+#include <Standard_ProgramError.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_StructureShadow, Vulkan_Structure)
+
+//=======================================================================
+//function : Vulkan_StructureShadow
+//purpose  :
+//=======================================================================
+Vulkan_StructureShadow::Vulkan_StructureShadow (const Handle(Graphic3d_StructureManager)& theManager,
+                                                const Handle(Vulkan_Structure)& theStructure)
+: Vulkan_Structure (theManager)
+{
+  Handle(Vulkan_StructureShadow) aShadow = Handle(Vulkan_StructureShadow)::DownCast (theStructure);
+  myParent = aShadow.IsNull() ? theStructure : aShadow->myParent;
+
+  ContainsFacet = myParent->ContainsFacet;
+  IsInfinite    = myParent->IsInfinite;
+  myBndBox      = myParent->BoundingBox();
+
+  Vulkan_Structure::SetTransformation (myParent->Transformation());
+  myInstancedStructure = const_cast<Vulkan_Structure*> (myParent->InstancedStructure());
+  myTrsfPers = myParent->TransformPersistence();
+
+  // reuse instanced structure API
+  myInstancedStructure = myParent.operator->();
+}
+
+// =======================================================================
+// function : Connect
+// purpose  :
+// =======================================================================
+void Vulkan_StructureShadow::Connect (Graphic3d_CStructure& )
+{
+  throw Standard_ProgramError("Error! Vulkan_StructureShadow::Connect() should not be called!");
+}
+
+// =======================================================================
+// function : Disconnect
+// purpose  :
+// =======================================================================
+void Vulkan_StructureShadow::Disconnect (Graphic3d_CStructure& )
+{
+  throw Standard_ProgramError("Error! Vulkan_StructureShadow::Disconnect() should not be called!");
+}
diff --git a/src/Vulkan/Vulkan_StructureShadow.hxx b/src/Vulkan/Vulkan_StructureShadow.hxx
new file mode 100644 (file)
index 0000000..e5886b8
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_StructureShadow_HeaderFile
+#define _Vulkan_StructureShadow_HeaderFile
+
+#include <Vulkan_Structure.hxx>
+
+//! Dummy structure which just redirects to groups of another structure.
+class Vulkan_StructureShadow : public Vulkan_Structure
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_StructureShadow, Vulkan_Structure)
+public:
+
+  //! Create empty structure
+  Standard_EXPORT Vulkan_StructureShadow (const Handle(Graphic3d_StructureManager)& theManager,
+                                          const Handle(Vulkan_Structure)& theStructure);
+
+public:
+
+  //! Raise exception on API misuse.
+  virtual void Connect (Graphic3d_CStructure& ) Standard_OVERRIDE;
+
+  //! Raise exception on API misuse.
+  virtual void Disconnect (Graphic3d_CStructure& ) Standard_OVERRIDE;
+
+private:
+
+  Handle(Vulkan_Structure) myParent;
+
+};
+
+#endif // _Vulkan_StructureShadow_HeaderFile
diff --git a/src/Vulkan/Vulkan_Surface.cxx b/src/Vulkan/Vulkan_Surface.cxx
new file mode 100644 (file)
index 0000000..f4a1cc5
--- /dev/null
@@ -0,0 +1,318 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#if defined(_WIN32)
+  #include <windows.h>
+
+  #define VK_USE_PLATFORM_WIN32_KHR 1
+#endif
+
+#include <Vulkan_Surface.hxx>
+
+#include <Aspect_Window.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_Fence.hxx>
+#include <Vulkan_Image.hxx>
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_Surface, Vulkan_Object)
+
+// =======================================================================
+// function : Vulkan_Surface
+// purpose  :
+// =======================================================================
+Vulkan_Surface::Vulkan_Surface()
+: mySwapFence (new Vulkan_Fence()),
+  myDepthImage (new Vulkan_Image()),
+  myVkSurface (NULL),
+  myVkSwapChain (NULL),
+  myVkFormat (new VkSurfaceFormatKHR())
+{
+  myVkFormat->format = VK_FORMAT_UNDEFINED;
+  myVkFormat->colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
+}
+
+// =======================================================================
+// function : ~Vulkan_Surface
+// purpose  :
+// =======================================================================
+Vulkan_Surface::~Vulkan_Surface()
+{
+  releaseSurface();
+}
+
+// =======================================================================
+// function : releaseSurface
+// purpose  :
+// =======================================================================
+void Vulkan_Surface::releaseSurface()
+{
+  mySwapFence->Release();
+  myDepthImage->Release();
+  for (size_t anImgIter = 0; anImgIter < myVkImageViews.size(); ++anImgIter)
+  {
+    VkImageView& aVkImageView = myVkImageViews[anImgIter];
+    if (aVkImageView != NULL)
+    {
+      Vulkan_AssertOnRelease("Vulkan_Surface");
+      vkDestroyImageView (myDevice->Device(), aVkImageView, myDevice->HostAllocator());
+      aVkImageView = NULL;
+    }
+  }
+  myVkImages.clear();
+  myVkImageViews.clear();
+  if (myVkSwapChain != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_Surface");
+    vkDestroySwapchainKHR (myDevice->Device(), myVkSwapChain, myDevice->HostAllocator());
+    myVkSwapChain = NULL;
+  }
+  if (myVkSurface != NULL)
+  {
+    Vulkan_AssertOnRelease("Vulkan_Surface");
+    vkDestroySurfaceKHR (myDevice->Instance(), myVkSurface, myDevice->HostAllocator());
+    myVkSurface = NULL;
+  }
+  myDevice.Nullify();
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool Vulkan_Surface::Init (const Handle(Vulkan_Device)& theDevice,
+                           const Handle(Aspect_Window)& theWindow)
+{
+  Release();
+  if (theDevice.IsNull()
+   || theDevice->Device() == NULL
+   || theWindow.IsNull())
+  {
+    return false;
+  }
+
+  if (!mySwapFence->Create (theDevice))
+  {
+    return false;
+  }
+
+  myDevice = theDevice;
+
+#if defined(_WIN32)
+  VkWin32SurfaceCreateInfoKHR aVkWin32SurfInfo;
+  aVkWin32SurfInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+  aVkWin32SurfInfo.pNext = NULL;
+  aVkWin32SurfInfo.flags = 0;
+  aVkWin32SurfInfo.hinstance = GetModuleHandleW (NULL);
+  aVkWin32SurfInfo.hwnd = (HWND )theWindow->NativeHandle();
+
+  VkResult aRes = vkCreateWin32SurfaceKHR (theDevice->Instance(), &aVkWin32SurfInfo, theDevice->HostAllocator(), &myVkSurface);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailureAndRelease ("unable to create surface", aRes);
+    return false;
+  }
+#else
+  int NOT_IMPLEMENTED = 0;
+#endif
+  if (myVkSurface == NULL)
+  {
+    return false;
+  }
+
+  VkBool32 isSupported = VK_FALSE;
+  aRes = vkGetPhysicalDeviceSurfaceSupportKHR (theDevice->PhysicalDevice(), 0, myVkSurface, &isSupported);
+  if (aRes != VK_SUCCESS || isSupported == VK_FALSE)
+  {
+    logFailureAndRelease ("surface not supported", aRes);
+    return false;
+  }
+  
+  mySize = CurrentSize();
+  if (mySize.x() == 0
+   || mySize.y() == 0)
+  {
+    return false;
+  }
+
+  if (!findFormat (theDevice, *myVkFormat))
+  {
+    Release();
+    return false;
+  }
+
+  {
+    VkSwapchainCreateInfoKHR aSwapChainInfo;
+    aSwapChainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+    aSwapChainInfo.pNext = NULL;
+    aSwapChainInfo.flags = 0;
+    aSwapChainInfo.surface = myVkSurface;
+    aSwapChainInfo.minImageCount = 2;
+    aSwapChainInfo.imageFormat = myVkFormat->format;
+    aSwapChainInfo.imageColorSpace = myVkFormat->colorSpace;
+    aSwapChainInfo.imageExtent.width  = mySize.x();
+    aSwapChainInfo.imageExtent.height = mySize.y();
+    aSwapChainInfo.imageArrayLayers = 1;
+    aSwapChainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+    aSwapChainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    aSwapChainInfo.queueFamilyIndexCount = 0;
+    aSwapChainInfo.pQueueFamilyIndices = NULL;
+    aSwapChainInfo.preTransform   = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
+    aSwapChainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+    aSwapChainInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;///theIsVSync ? VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR;
+    aSwapChainInfo.clipped = VK_TRUE;
+    aSwapChainInfo.oldSwapchain = VK_NULL_HANDLE;
+
+    aRes = vkCreateSwapchainKHR (theDevice->Device(), &aSwapChainInfo, theDevice->HostAllocator(), &myVkSwapChain);
+    if (aRes != VK_SUCCESS)
+    {
+      logFailureAndRelease ("failed to create swapchain", aRes);
+      return false;
+    }
+  }
+
+  {
+    uint32_t aNbSwapChainImages = 0;
+    aRes = vkGetSwapchainImagesKHR (theDevice->Device(), myVkSwapChain, &aNbSwapChainImages, NULL);
+    if (aRes != VK_SUCCESS)
+    {
+      logFailureAndRelease ("failed to get swapchain images count", aRes);
+      return false;
+    }
+
+    myVkImages.resize (aNbSwapChainImages, NULL);
+    aRes = vkGetSwapchainImagesKHR (theDevice->Device(), myVkSwapChain, &aNbSwapChainImages, myVkImages.data());
+    if (aRes != VK_SUCCESS)
+    {
+      logFailureAndRelease ("failed to get swapchain images", aRes);
+      return false;
+    }
+  }
+
+  myVkImageViews.resize (myVkImages.size(), NULL);
+  for (uint32_t anImgIter = 0; anImgIter < myVkImages.size(); ++anImgIter)
+  {
+    VkImageViewCreateInfo aImgViewInfo = {};
+    aImgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+    aImgViewInfo.pNext = NULL;
+    aImgViewInfo.flags = 0;
+    aImgViewInfo.image = myVkImages[anImgIter];
+    aImgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    aImgViewInfo.format = myVkFormat->format;
+    aImgViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
+    aImgViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
+    aImgViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
+    aImgViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
+    aImgViewInfo.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+    aImgViewInfo.subresourceRange.baseMipLevel   = 0;
+    aImgViewInfo.subresourceRange.levelCount     = 1;
+    aImgViewInfo.subresourceRange.baseArrayLayer = 0;
+    aImgViewInfo.subresourceRange.layerCount     = 1;
+
+    aRes = vkCreateImageView (theDevice->Device(), &aImgViewInfo, theDevice->HostAllocator(), &myVkImageViews[anImgIter]);
+    if (aRes != VK_SUCCESS)
+    {
+      logFailureAndRelease ("failed to create image view", aRes);
+      return false;
+    }
+  }
+
+  if (!myDepthImage->CreateDepthStencil (myDevice, mySize))
+  {
+    Release();
+    return false;
+  }
+
+  return true;
+}
+
+// =======================================================================
+// function : findFormat
+// purpose  :
+// =======================================================================
+bool Vulkan_Surface::findFormat (const Handle(Vulkan_Device)& theDevice,
+                                 VkSurfaceFormatKHR& theFormat)
+{
+  if (myVkSurface == NULL)
+  {
+    return false;
+  }
+
+  uint32_t aNbSurfFormats = 0;
+  VkResult aRes = vkGetPhysicalDeviceSurfaceFormatsKHR (theDevice->PhysicalDevice(), myVkSurface, &aNbSurfFormats, NULL);
+  if (aRes != VK_SUCCESS
+   || aNbSurfFormats == 0)
+  {
+    logFailure ("failed to get surface formats count", aRes);
+    return false;
+  }
+
+  std::vector<VkSurfaceFormatKHR> aVkSurfFormats (aNbSurfFormats);
+  aRes = vkGetPhysicalDeviceSurfaceFormatsKHR (theDevice->PhysicalDevice(), myVkSurface, &aNbSurfFormats, aVkSurfFormats.data());
+  if (aRes != VK_SUCCESS)
+  {
+    logFailure ("failed to get surface formats", aRes);
+    return false;
+  }
+
+  theFormat = aVkSurfFormats[0];
+  return true;
+}
+
+// =======================================================================
+// function : CurrentSize
+// purpose  :
+// =======================================================================
+Graphic3d_Vec2u Vulkan_Surface::CurrentSize()
+{
+  if (myVkSurface == NULL)
+  {
+    return Graphic3d_Vec2u (0, 0);
+  }
+
+  VkSurfaceCapabilitiesKHR aVkSurfCaps;
+  VkResult aRes = vkGetPhysicalDeviceSurfaceCapabilitiesKHR (myDevice->PhysicalDevice(), myVkSurface, &aVkSurfCaps);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailure ("failed to get surface capabilities", aRes);
+    return Graphic3d_Vec2u (0, 0);
+  }
+
+  return Graphic3d_Vec2u (aVkSurfCaps.currentExtent.width, aVkSurfCaps.currentExtent.height);
+}
+
+// =======================================================================
+// function : AcquireNextImage
+// purpose  :
+// =======================================================================
+bool Vulkan_Surface::AcquireNextImage (uint32_t& theSwapChainIndex)
+{
+  theSwapChainIndex = 0;
+  if (myDevice.IsNull())
+  {
+    return false;
+  }
+
+  VkResult aRes = vkAcquireNextImageKHR (myDevice->Device(), myVkSwapChain, UINT64_MAX, VK_NULL_HANDLE, mySwapFence->Fence(), &theSwapChainIndex);
+  if (aRes != VK_SUCCESS)
+  {
+    logFailure ("failed to get next swapchain image", aRes);
+    return false;
+  }
+
+  return mySwapFence->Wait()
+      && mySwapFence->Reset();
+}
diff --git a/src/Vulkan/Vulkan_Surface.hxx b/src/Vulkan/Vulkan_Surface.hxx
new file mode 100644 (file)
index 0000000..29aeff5
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_Surface_HeaderFile
+#define _Vulkan_Surface_HeaderFile
+
+#include <Graphic3d_Vec2.hxx>
+#include <Vulkan_Object.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <memory>
+#include <vector>
+
+class Aspect_Window;
+class Vulkan_Device;
+class Vulkan_Fence;
+class Vulkan_Image;
+
+//! This class defines an Vulkan surface.
+class Vulkan_Surface : public Vulkan_Object
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_Surface, Vulkan_Object)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_Surface();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Vulkan_Surface();
+
+  //! Perform initialization.
+  Standard_EXPORT bool Init (const Handle(Vulkan_Device)& theDevice,
+                             const Handle(Aspect_Window)& theWindow);
+
+  //! Return surface.
+  VkSurfaceKHR Surface() const { return myVkSurface; }
+
+  //! Return swap chain.
+  VkSwapchainKHR SwapChain() const { return myVkSwapChain; }
+
+  //! Return the swap chain length.
+  uint32_t SwapChainSize() const { return (uint32_t )myVkImageViews.size(); }
+
+  //! Return images within swap chain.
+  const std::vector<VkImage>& Images() const { return myVkImages; }
+
+  //! Return image views within swap chain.
+  const std::vector<VkImageView>& ImageViews() const { return myVkImageViews; }
+
+  //! Return color surface format.
+  const VkSurfaceFormatKHR& ColorFormat() const { return *myVkFormat; }
+
+  //! Return depth image.
+  const Handle(Vulkan_Image)& DepthImage() const { return myDepthImage; }
+
+  //! Return surface size.
+  const Graphic3d_Vec2u& Size() const { return mySize; }
+
+  //! Fetch actual surface size.
+  Graphic3d_Vec2u CurrentSize();
+
+  //! Acquire next image from swap chain, @sa vkAcquireNextImageKHR().
+  Standard_EXPORT bool AcquireNextImage (uint32_t& theSwapChainIndex);
+
+protected:
+
+  //! Find supported format.
+  Standard_EXPORT bool findFormat (const Handle(Vulkan_Device)& theDevice,
+                                   VkSurfaceFormatKHR& theFormat);
+
+  //! Release the object.
+  virtual void release() Standard_OVERRIDE { releaseSurface(); }
+
+  //! Release the object, @sa vkDestroySurfaceKHR().
+  Standard_EXPORT void releaseSurface();
+
+protected:
+
+  Handle(Vulkan_Fence) mySwapFence;
+  Handle(Vulkan_Image) myDepthImage;
+  VkSurfaceKHR         myVkSurface;
+  VkSwapchainKHR       myVkSwapChain;
+  Graphic3d_Vec2u      mySize;
+  std::vector<VkImage>     myVkImages;
+  std::vector<VkImageView> myVkImageViews;
+  std::shared_ptr<VkSurfaceFormatKHR> myVkFormat;
+
+};
+
+#endif // _Vulkan_Surface_HeaderFile
diff --git a/src/Vulkan/Vulkan_View.cxx b/src/Vulkan/Vulkan_View.cxx
new file mode 100644 (file)
index 0000000..9aeb8bc
--- /dev/null
@@ -0,0 +1,795 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Vulkan_View.hxx>
+
+#include <BVH_LinearBuilder.hxx>
+#include <Graphic3d_FrameStats.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Vulkan_Buffer.hxx>
+#include <Vulkan_Caps.hxx>
+#include <Vulkan_CommandBuffer.hxx>
+#include <Vulkan_CommandPool.hxx>
+#include <Vulkan_Context.hxx>
+#include <Vulkan_DescriptorPool.hxx>
+#include <Vulkan_DescriptorSetLayout.hxx>
+#include <Vulkan_Device.hxx>
+#include <Vulkan_Fence.hxx>
+#include <Vulkan_FrameBuffer.hxx>
+#include <Vulkan_FrameStats.hxx>
+#include <Vulkan_GraphicDriver.hxx>
+#include <Vulkan_Group.hxx>
+#include <Vulkan_Image.hxx>
+#include <Vulkan_Pipeline.hxx>
+#include <Vulkan_PipelineLayout.hxx>
+#include <Vulkan_RenderPass.hxx>
+#include <Vulkan_Surface.hxx>
+#include <Vulkan_Shader.hxx>
+#include <Vulkan_Structure.hxx>
+
+#include "../Graphic3d/Graphic3d_Structure.pxx"
+
+#include <vulkan/vulkan.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(Vulkan_View, Graphic3d_CView)
+
+// =======================================================================
+// function : Constructor
+// purpose  :
+// =======================================================================
+Vulkan_View::Vulkan_View (const Handle(Graphic3d_StructureManager)& theMgr,
+                          const Handle(Vulkan_GraphicDriver)& theDriver)
+: Graphic3d_CView  (theMgr),
+  myDriver         (theDriver.get()),
+  myWasRedrawnGL   (Standard_False),
+  myBackfacing     (Graphic3d_TOBM_AUTOMATIC),
+  myLayer (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1, new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth)),
+  mySwapInterval (0),
+  ///myZLayers        (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1),
+  //myFboColorFormat       (GL_RGBA8),
+  //myFboDepthFormat       (GL_DEPTH24_STENCIL8),
+  myFrameCounter         (0),
+  myHasFboBlit           (Standard_True),
+  myToDisableOIT         (Standard_False),
+  myToDisableOITMSAA     (Standard_False),
+  myToDisableMSAA        (Standard_False),
+  myTransientDrawToFront (Standard_True),
+  myBackBufferRestored   (Standard_False),
+  myIsImmediateDrawn     (Standard_False)
+  //myTextureParams   (new OpenGl_Aspects()),
+  //myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
+  //myBgTextureArray  (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)),
+{
+  Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TOLS_AMBIENT);
+  aLight->SetHeadlight (false);
+  aLight->SetColor (Quantity_NOC_WHITE);
+  myNoShadingLight = new Graphic3d_LightSet();
+  myNoShadingLight->Add (aLight);
+
+  /*myMainSceneFbos[0]         = new OpenGl_FrameBuffer();
+  myMainSceneFbos[1]         = new OpenGl_FrameBuffer();
+  myMainSceneFbosOit[0]      = new OpenGl_FrameBuffer();
+  myMainSceneFbosOit[1]      = new OpenGl_FrameBuffer();
+  myImmediateSceneFbos[0]    = new OpenGl_FrameBuffer();
+  myImmediateSceneFbos[1]    = new OpenGl_FrameBuffer();
+  myImmediateSceneFbosOit[0] = new OpenGl_FrameBuffer();
+  myImmediateSceneFbosOit[1] = new OpenGl_FrameBuffer();
+  myOpenGlFBO                = new OpenGl_FrameBuffer();
+  myOpenGlFBO2               = new OpenGl_FrameBuffer();
+  myRaytraceFBO1[0]          = new OpenGl_FrameBuffer();
+  myRaytraceFBO1[1]          = new OpenGl_FrameBuffer();
+  myRaytraceFBO2[0]          = new OpenGl_FrameBuffer();
+  myRaytraceFBO2[1]          = new OpenGl_FrameBuffer();*/
+}
+
+// =======================================================================
+// function : Destructor
+// purpose  :
+// =======================================================================
+Vulkan_View::~Vulkan_View()
+{
+  ///ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
+  ///OpenGl_Element::Destroy (NULL, myBgGradientArray);
+  ///OpenGl_Element::Destroy (NULL, myBgTextureArray);
+  ///OpenGl_Element::Destroy (NULL, myTextureParams);
+}
+
+// =======================================================================
+// function : ReleaseGlResources
+// purpose  :
+// =======================================================================
+/*void Vulkan_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
+{
+  myGraduatedTrihedron.Release (theCtx.get());
+  myFrameStatsPrs.Release (theCtx.get());
+
+  if (!myTextureEnv.IsNull())
+  {
+    if (!theCtx.IsNull())
+    {
+      for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
+      {
+        theCtx->DelayedRelease (aTextureIter.ChangeValue());
+        aTextureIter.ChangeValue().Nullify();
+      }
+    }
+    myTextureEnv.Nullify();
+  }
+
+  if (myTextureParams != NULL)
+  {
+    myTextureParams->Release (theCtx.get());
+  }
+  if (myBgGradientArray != NULL)
+  {
+    myBgGradientArray->Release (theCtx.get());
+  }
+  if (myBgTextureArray != NULL)
+  {
+    myBgTextureArray->Release (theCtx.get());
+  }
+
+  myMainSceneFbos[0]        ->Release (theCtx.get());
+  myMainSceneFbos[1]        ->Release (theCtx.get());
+  myMainSceneFbosOit[0]     ->Release (theCtx.get());
+  myMainSceneFbosOit[1]     ->Release (theCtx.get());
+  myImmediateSceneFbos[0]   ->Release (theCtx.get());
+  myImmediateSceneFbos[1]   ->Release (theCtx.get());
+  myImmediateSceneFbosOit[0]->Release (theCtx.get());
+  myImmediateSceneFbosOit[1]->Release (theCtx.get());
+  myOpenGlFBO               ->Release (theCtx.get());
+  myOpenGlFBO2              ->Release (theCtx.get());
+  myFullScreenQuad           .Release (theCtx.get());
+  myFullScreenQuadFlip       .Release (theCtx.get());
+
+  releaseRaytraceResources (theCtx);
+}*/
+
+// =======================================================================
+// function : Remove
+// purpose  :
+// =======================================================================
+void Vulkan_View::Remove()
+{
+  if (IsRemoved())
+  {
+    return;
+  }
+
+  myDriver->RemoveView (this);
+  /// TODO
+  myPlatformWindow.Nullify();
+
+  Graphic3d_CView::Remove();
+}
+
+// =======================================================================
+// function : SetLocalOrigin
+// purpose  :
+// =======================================================================
+void Vulkan_View::SetLocalOrigin (const gp_XYZ& theOrigin)
+{
+  myLocalOrigin = theOrigin;
+  /**const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
+  if (!aCtx.IsNull())
+  {
+    aCtx->ShaderManager()->SetLocalOrigin (theOrigin);
+  }*/
+}
+
+// =======================================================================
+// function : SetTextureEnv
+// purpose  :
+// =======================================================================
+void Vulkan_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& )
+{
+  //
+}
+
+// =======================================================================
+// function : SetImmediateModeDrawToFront
+// purpose  :
+// =======================================================================
+Standard_Boolean Vulkan_View::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
+{
+  const Standard_Boolean aPrevMode = myTransientDrawToFront;
+  myTransientDrawToFront = theDrawToFrontBuffer;
+  return aPrevMode;
+}
+
+
+// =======================================================================
+// function : initSwapChain
+// purpose  :
+// =======================================================================
+bool Vulkan_View::initSwapChain (const Handle(Aspect_Window)& theWindow,
+                                 const Aspect_RenderingContext theContext)
+{
+  (void )theContext;
+  myPlatformWindow = theWindow;
+  mySwapInterval = myDriver->Options()->swapInterval;
+  const Handle(Vulkan_Device)& aDevice = myDriver->Device();
+  if (aDevice->Device() == NULL
+  && !aDevice->Init (myDriver->Options()))
+  {
+    return false;
+  }
+
+  if (!mySurface.IsNull())
+  {
+    mySurface->Release();
+  }
+
+  mySurface = new Vulkan_Surface();
+  return mySurface->Init (aDevice, theWindow);
+}
+
+// =======================================================================
+// function : SetWindow
+// purpose  :
+// =======================================================================
+void Vulkan_View::SetWindow (const Handle(Aspect_Window)& theWindow,
+                             const Aspect_RenderingContext theContext)
+{
+  if (!initSwapChain (theWindow, theContext))
+  {
+    throw Standard_ProgramError ("Vulkan_View::SetWindow() failed");
+  }
+
+  myHasFboBlit = Standard_True;
+  Invalidate();
+}
+
+// =======================================================================
+// function : Resized
+// purpose  :
+// =======================================================================
+void Vulkan_View::Resized()
+{
+  if (myPlatformWindow.IsNull()
+   || mySurface.IsNull())
+  {
+    return;
+  }
+
+  /// TODO
+}
+
+// =======================================================================
+// function : BufferDump
+// purpose  :
+// =======================================================================
+Standard_Boolean Vulkan_View::BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType)
+{
+  (void )theImage;
+  (void )theBufferType;
+  return false;
+}
+
+//=======================================================================
+//function : AddZLayer
+//purpose  :
+//=======================================================================
+void Vulkan_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
+{
+  ///myZLayers.AddLayer (theLayerId);
+}
+
+//=======================================================================
+//function : RemoveZLayer
+//purpose  :
+//=======================================================================
+void Vulkan_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
+{
+  ///myZLayers.RemoveLayer (theLayerId);
+}
+
+//=======================================================================
+//function : SetZLayerSettings
+//purpose  :
+//=======================================================================
+void Vulkan_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
+                                     const Graphic3d_ZLayerSettings& theSettings)
+{
+  ///myZLayers.SetLayerSettings (theLayerId, theSettings);
+}
+
+//=======================================================================
+//function : ZLayerMax
+//purpose  :
+//=======================================================================
+Standard_Integer Vulkan_View::ZLayerMax() const
+{
+  Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default;
+  /*for (OpenGl_LayerSeqIds::Iterator aMapIt(myZLayers.LayerIDs()); aMapIt.More(); aMapIt.Next())
+  {
+    aLayerMax = Max (aLayerMax, aMapIt.Value());
+  }*/
+
+  return aLayerMax;
+}
+
+//=======================================================================
+//function : InvalidateZLayerBoundingBox
+//purpose  :
+//=======================================================================
+void Vulkan_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const
+{
+  myLayer.InvalidateBoundingBox();
+  /*if (myZLayers.LayerIDs().IsBound (theLayerId))
+  {
+    myZLayers.Layer (theLayerId).InvalidateBoundingBox();
+  }
+  else
+  {
+    const Standard_Integer aLayerMax = ZLayerMax();
+    for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < aLayerMax; ++aLayerId)
+    {
+      if (myZLayers.LayerIDs().IsBound (aLayerId))
+      {
+        const OpenGl_Layer& aLayer = myZLayers.Layer (aLayerId);
+        if (aLayer.NbOfTransformPersistenceObjects() > 0)
+        {
+          aLayer.InvalidateBoundingBox();
+        }
+      }
+    }
+  }*/
+}
+
+//=======================================================================
+//function : ZLayerBoundingBox
+//purpose  :
+//=======================================================================
+Bnd_Box Vulkan_View::ZLayerBoundingBox (const Graphic3d_ZLayerId        theLayerId,
+                                        const Handle(Graphic3d_Camera)& theCamera,
+                                        const Standard_Integer          theWindowWidth,
+                                        const Standard_Integer          theWindowHeight,
+                                        const Standard_Boolean          theToIncludeAuxiliary) const
+{
+  Bnd_Box aBox;
+  aBox = myLayer.BoundingBox (Identification(),
+                              theCamera,
+                              theWindowWidth,
+                              theWindowHeight,
+                              theToIncludeAuxiliary);
+  /*if (myZLayers.LayerIDs().IsBound (theLayerId))
+  {
+    aBox = myZLayers.Layer (theLayerId).BoundingBox (Identification(),
+                                                     theCamera,
+                                                     theWindowWidth,
+                                                     theWindowHeight,
+                                                     theToIncludeAuxiliary);
+  }
+
+  // add bounding box of gradient/texture background for proper Z-fit
+  if (theToIncludeAuxiliary
+   && theLayerId == Graphic3d_ZLayerId_BotOSD
+   && (myBgTextureArray->IsDefined()
+    || myBgGradientArray->IsDefined()))
+  {
+    // Background is drawn using 2D transformation persistence
+    // (e.g. it is actually placed in 3D coordinates within active camera position).
+    // We add here full-screen plane with 2D transformation persistence
+    // for simplicity (myBgTextureArray might define a little bit different options
+    // but it is updated within ::Render())
+    const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix();
+    const Graphic3d_Mat4d& aWorldViewMat  = theCamera->OrientationMatrix();
+    Graphic3d_BndBox3d aBox2d (Graphic3d_Vec3d (0.0, 0.0, 0.0),
+                               Graphic3d_Vec3d (double(theWindowWidth), double(theWindowHeight), 0.0));
+
+    Graphic3d_TransformPers aTrsfPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER);
+    aTrsfPers.Apply (theCamera,
+                     aProjectionMat,
+                     aWorldViewMat,
+                     theWindowWidth,
+                     theWindowHeight,
+                     aBox2d);
+    aBox.Add (gp_Pnt (aBox2d.CornerMin().x(), aBox2d.CornerMin().y(), aBox2d.CornerMin().z()));
+    aBox.Add (gp_Pnt (aBox2d.CornerMax().x(), aBox2d.CornerMax().y(), aBox2d.CornerMax().z()));
+  }*/
+
+  return aBox;
+}
+
+//=======================================================================
+//function : considerZoomPersistenceObjects
+//purpose  :
+//=======================================================================
+void Vulkan_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
+{
+  myLayer.InvalidateBVHData();
+  //
+}
+
+//=======================================================================
+//function : considerZoomPersistenceObjects
+//purpose  :
+//=======================================================================
+Standard_Real Vulkan_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId        theLayerId,
+                                                           const Handle(Graphic3d_Camera)& theCamera,
+                                                           const Standard_Integer          theWindowWidth,
+                                                           const Standard_Integer          theWindowHeight) const
+{
+  /*if (myZLayers.LayerIDs().IsBound (theLayerId))
+  {
+    return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(),
+                                                                        theCamera,
+                                                                        theWindowWidth,
+                                                                        theWindowHeight);
+  }*/
+
+  return 1.0;
+}
+
+//=======================================================================
+//function : FBO
+//purpose  :
+//=======================================================================
+Handle(Standard_Transient) Vulkan_View::FBO() const
+{
+  return NULL; ///Handle(Standard_Transient)(myFBO);
+}
+
+//=======================================================================
+//function : SetFBO
+//purpose  :
+//=======================================================================
+void Vulkan_View::SetFBO (const Handle(Standard_Transient)& theFbo)
+{
+  ///myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
+}
+
+//=======================================================================
+//function : FBOCreate
+//purpose  :
+//=======================================================================
+Handle(Standard_Transient) Vulkan_View::FBOCreate (const Standard_Integer theWidth,
+                                                   const Standard_Integer theHeight)
+{
+  return NULL;//return myWorkspace->FBOCreate (theWidth, theHeight);
+}
+
+//=======================================================================
+//function : FBORelease
+//purpose  :
+//=======================================================================
+void Vulkan_View::FBORelease (Handle(Standard_Transient)& theFbo)
+{
+  /*Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
+  if (aFrameBuffer.IsNull())
+  {
+    return;
+  }
+
+  myWorkspace->FBORelease (aFrameBuffer);
+  theFbo.Nullify();*/
+}
+
+//=======================================================================
+//function : FBOGetDimensions
+//purpose  :
+//=======================================================================
+void Vulkan_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo,
+                                    Standard_Integer& theWidth,
+                                    Standard_Integer& theHeight,
+                                    Standard_Integer& theWidthMax,
+                                    Standard_Integer& theHeightMax)
+{
+  /*const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
+  if (aFrameBuffer.IsNull())
+  {
+    return;
+  }
+
+  theWidth     = aFrameBuffer->GetVPSizeX(); // current viewport size
+  theHeight    = aFrameBuffer->GetVPSizeY();
+  theWidthMax  = aFrameBuffer->GetSizeX(); // texture size
+  theHeightMax = aFrameBuffer->GetSizeY();*/
+}
+
+//=======================================================================
+//function : FBOChangeViewport
+//purpose  :
+//=======================================================================
+void Vulkan_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo,
+                                     const Standard_Integer theWidth,
+                                     const Standard_Integer theHeight)
+{
+  /*const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
+  if (aFrameBuffer.IsNull())
+  {
+    return;
+  }
+
+  aFrameBuffer->ChangeViewport (theWidth, theHeight);*/
+}
+
+//=======================================================================
+//function : displayStructure
+//purpose  :
+//=======================================================================
+void Vulkan_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure,
+                                    const Standard_Integer              thePriority)
+{
+  const Graphic3d_ZLayerId aZLayer = theStructure->ZLayer();
+  myLayer.Add (theStructure.get(), thePriority);
+  ///myZLayers.AddStructure (aStruct, aZLayer, thePriority);
+}
+
+//=======================================================================
+//function : eraseStructure
+//purpose  :
+//=======================================================================
+void Vulkan_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure)
+{
+  int aPrior = 0;
+  myLayer.Remove (theStructure.get(), aPrior);
+  ///const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
+  ///myZLayers.RemoveStructure (aStruct);
+}
+
+//=======================================================================
+//function : changeZLayer
+//purpose  :
+//=======================================================================
+void Vulkan_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure,
+                                const Graphic3d_ZLayerId theNewLayerId)
+{
+  const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
+  ///const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
+  ///myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId);
+  Update (anOldLayer);
+  Update (theNewLayerId);
+}
+
+//=======================================================================
+//function : changePriority
+//purpose  :
+//=======================================================================
+void Vulkan_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure,
+                                  const Standard_Integer theNewPriority)
+{
+  const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
+  ///const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
+  ///myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority);
+}
+
+//=======================================================================
+//function : DiagnosticInformation
+//purpose  :
+//=======================================================================
+void Vulkan_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
+                                         Graphic3d_DiagnosticInfo theFlags) const
+{
+  const Handle(Vulkan_Device)& aDevice = myDriver->Device();
+  if (aDevice.IsNull())
+  {
+    return;
+  }
+
+  aDevice->DiagnosticInformation (theDict, theFlags);
+  if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
+  {
+    if (!mySurface.IsNull())
+    {
+      const Graphic3d_Vec2u aSize = mySurface->CurrentSize();
+      TCollection_AsciiString aViewport = TCollection_AsciiString() + int(aSize.x()) + "x" + int(aSize.y());
+      theDict.ChangeFromIndex (theDict.Add ("Viewport", aViewport)) = aViewport;
+    }
+    TCollection_AsciiString aResRatio (myRenderParams.ResolutionRatio());
+    theDict.ChangeFromIndex (theDict.Add ("ResolutionRatio", aResRatio)) = aResRatio;
+  }
+}
+
+//=======================================================================
+//function : StatisticInformation
+//purpose  :
+//=======================================================================
+void Vulkan_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
+{
+  if (const Handle(Vulkan_Device)& aDevice = myDriver->Device())
+  {
+    const Handle(Vulkan_FrameStats)& aStats = aDevice->FrameStats();
+    aStats->FormatStats (theDict, myRenderParams.CollectedStats);
+  }
+}
+
+//=======================================================================
+//function : StatisticInformation
+//purpose  :
+//=======================================================================
+TCollection_AsciiString Vulkan_View::StatisticInformation() const
+{
+  if (const Handle(Vulkan_Device)& aDevice = myDriver->Device())
+  {
+    const Handle(Vulkan_FrameStats)& aStats = aDevice->FrameStats();
+    return aStats->FormatStats (myRenderParams.CollectedStats);
+  }
+  return TCollection_AsciiString();
+}
+
+//=======================================================================
+//function : Redraw
+//purpose  :
+//=======================================================================
+void Vulkan_View::Redraw()
+{
+  if (!myCamera->IsZeroToOneDepth())
+  {
+    myCamera->SetZeroToOneDepth (true);
+  }
+
+  const Handle(Vulkan_Device)& aDevice = myDriver->Device();
+  if (aDevice->Device() == NULL
+   || mySurface.IsNull()
+   || mySurface->Surface() == NULL)
+  {
+    return;
+  }
+
+  const Graphic3d_Vec2u aSurfSize = mySurface->Size();
+  if (aSurfSize.x() == 0
+   || aSurfSize.y() == 0)
+  {
+    return;
+  }
+
+  if (myContext.IsNull())
+  {
+    myContext = new Vulkan_Context (aDevice);
+    Handle(Vulkan_RenderPass) aRenderPass = new Vulkan_RenderPass();
+    if (!aRenderPass->Create (aDevice, mySurface))
+    {
+      return;
+    }
+    myContext->SetRenderPass (aRenderPass);
+  }
+
+  VkQueue aVkQueue = NULL;
+  vkGetDeviceQueue (aDevice->Device(), 0, 0, &aVkQueue);
+
+  if (!myContext->ResetState (myCamera))
+  {
+    return;
+  }
+
+  uint32_t aVKSwapChainIndex = 0;
+  if (!mySurface->AcquireNextImage (aVKSwapChainIndex))
+  {
+    return;
+  }
+
+  static std::vector<Handle(Vulkan_FrameBuffer)> aFrameBuffers;
+  aFrameBuffers.resize (mySurface->SwapChainSize());
+  Handle(Vulkan_FrameBuffer)& aFrameBuffer = aFrameBuffers[aVKSwapChainIndex];
+  if (aFrameBuffer.IsNull())
+  {
+    aFrameBuffer = new Vulkan_FrameBuffer();
+  }
+  if (!aFrameBuffer->Create (myContext->RenderPass(), mySurface, aVKSwapChainIndex))
+  {
+    return;
+  }
+
+  Handle(Vulkan_CommandBuffer) aCmdBuffer = myContext->CommandPool()->AllocateBuffer();
+  myContext->SetCommandBuffer (aCmdBuffer);
+  {
+    const VkImage aVkImage = mySurface->Images()[aVKSwapChainIndex];
+    aCmdBuffer->BeginCommandBuffer (myContext->RenderPass(), aFrameBuffer);
+    {
+      const Graphic3d_Vec4& aBgColor = myBgColor;
+      aCmdBuffer->BeginRenderPass (myContext->RenderPass(), aFrameBuffer, aSurfSize, &aBgColor);
+      {
+        for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aPriorIter (myLayer.ArrayOfStructures()); aPriorIter.More(); aPriorIter.Next())
+        {
+          for (Vulkan_Structure::StructIterator aStructIter (aPriorIter.Value()); aStructIter.More(); aStructIter.Next())
+          {
+            const Vulkan_Structure* aStruct = aStructIter.Value();
+            aStruct->Render (myContext);
+          }
+        }
+      }
+      aCmdBuffer->EndRenderPass();
+
+      VkImageMemoryBarrier aVkImgMemBarrier = {};
+      aVkImgMemBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+      aVkImgMemBarrier.pNext = NULL;
+      aVkImgMemBarrier.srcAccessMask = 0;
+      aVkImgMemBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_MEMORY_READ_BIT;
+      aVkImgMemBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+      aVkImgMemBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+      aVkImgMemBarrier.srcQueueFamilyIndex = 0;
+      aVkImgMemBarrier.dstQueueFamilyIndex = 0;
+      aVkImgMemBarrier.image = aVkImage;
+      aVkImgMemBarrier.subresourceRange = {VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
+
+      vkCmdPipelineBarrier (aCmdBuffer->CommandBuffer(),
+                            VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                            VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                            0,
+                            0, NULL,
+                            0, NULL,
+                            1, &aVkImgMemBarrier);
+    }
+    aCmdBuffer->EndCommandBuffer();
+  }
+
+///
+
+       const VkPipelineStageFlags aVkWaitMask = VkPipelineStageFlagBits::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+       VkSubmitInfo aVkSubmitInfo;
+  aVkSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+  aVkSubmitInfo.pNext = NULL;
+  aVkSubmitInfo.waitSemaphoreCount = 0;
+  aVkSubmitInfo.pWaitSemaphores = NULL;
+  aVkSubmitInfo.pWaitDstStageMask = &aVkWaitMask;
+  aVkSubmitInfo.commandBufferCount = 1;
+  aVkSubmitInfo.pCommandBuffers = &aCmdBuffer->CommandBuffer();
+  aVkSubmitInfo.signalSemaphoreCount = 0;
+  aVkSubmitInfo.pSignalSemaphores = NULL;
+
+  VkResult aRes = vkQueueSubmit (aVkQueue, 1, &aVkSubmitInfo, VK_NULL_HANDLE);
+       if (aRes != VkResult::VK_SUCCESS)
+       {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Window, failed to submit command buffer: ") + Vulkan_Device::FormatVkError (aRes));
+    return;
+       }
+
+  aRes = vkQueueWaitIdle (aVkQueue);
+       if (aRes != VkResult::VK_SUCCESS)
+       {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Window, failed to wait for queuer: ") + Vulkan_Device::FormatVkError (aRes));
+    return;
+       }
+
+  const VkSwapchainKHR aSwapChain = mySurface->SwapChain();
+       VkResult aResults = VkResult::VK_SUCCESS;
+       VkPresentInfoKHR aVkPresentInfo;
+  aVkPresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
+  aVkPresentInfo.pNext = NULL;
+  aVkPresentInfo.waitSemaphoreCount = 0;
+  aVkPresentInfo.pWaitSemaphores = NULL;
+  aVkPresentInfo.swapchainCount = 1;
+  aVkPresentInfo.pSwapchains = &aSwapChain;
+  aVkPresentInfo.pImageIndices = &aVKSwapChainIndex;
+  aVkPresentInfo.pResults = &aResults;
+
+  aRes = vkQueuePresentKHR (aVkQueue, &aVkPresentInfo);
+       if (aRes != VkResult::VK_SUCCESS
+   || aResults != VkResult::VK_SUCCESS)
+       {
+    Message::DefaultMessenger()->Send (TCollection_AsciiString ("Vulkan_Window, failed to present swapchain: ")
+                                     + Vulkan_Device::FormatVkError (aRes != VkResult::VK_SUCCESS ? aRes : aResults));
+    return;
+       }
+}
+
+//=======================================================================
+//function : RedrawImmediate
+//purpose  :
+//=======================================================================
+void Vulkan_View::RedrawImmediate()
+{
+  Redraw();
+}
+
+//=======================================================================
+//function : Invalidate
+//purpose  :
+//=======================================================================
+void Vulkan_View::Invalidate()
+{
+  //
+}
diff --git a/src/Vulkan/Vulkan_View.hxx b/src/Vulkan/Vulkan_View.hxx
new file mode 100644 (file)
index 0000000..808b6af
--- /dev/null
@@ -0,0 +1,441 @@
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Vulkan_View_HeaderFile
+#define _Vulkan_View_HeaderFile
+
+#include <Graphic3d_CView.hxx>
+#include <Graphic3d_Layer.hxx>
+
+class Vulkan_Caps;
+class Vulkan_Context;
+class Vulkan_Fence;
+class Vulkan_GraphicDriver;
+class Vulkan_Surface;
+
+//! Implementation of Vulkan view.
+class Vulkan_View : public Graphic3d_CView
+{
+  DEFINE_STANDARD_RTTIEXT(Vulkan_View, Graphic3d_CView)
+public:
+
+  //! Constructor.
+  Standard_EXPORT Vulkan_View (const Handle(Graphic3d_StructureManager)& theMgr,
+                               const Handle(Vulkan_GraphicDriver)& theDriver);
+
+  //! Default destructor.
+  Standard_EXPORT virtual ~Vulkan_View();
+
+  ///Standard_EXPORT void ReleaseGlResources (const Handle(OpenGl_Context)& theCtx);
+
+  //! Deletes and erases the view.
+  Standard_EXPORT virtual void Remove() Standard_OVERRIDE;
+
+  //! @param theDrawToFrontBuffer Advanced option to modify rendering mode:
+  //! 1. TRUE.  Drawing immediate mode structures directly to the front buffer over the scene image.
+  //! Fast, so preferred for interactive work (used by default).
+  //! However these extra drawings will be missed in image dump since it is performed from back buffer.
+  //! Notice that since no pre-buffering used the V-Sync will be ignored and rendering could be seen
+  //! in run-time (in case of slow hardware) and/or tearing may appear.
+  //! So this is strongly recommended to draw only simple (fast) structures.
+  //! 2. FALSE. Drawing immediate mode structures to the back buffer.
+  //! The complete scene is redrawn first, so this mode is slower if scene contains complex data and/or V-Sync
+  //! is turned on. But it works in any case and is especially useful for view dump because the dump image is read
+  //! from the back buffer.
+  //! @return previous mode.
+  Standard_EXPORT virtual Standard_Boolean SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer) Standard_OVERRIDE;
+
+  //! Creates and maps rendering window to the view.
+  //! @param theWindow [in] the window.
+  //! @param theContext [in] the rendering context. If NULL the context will be created internally.
+  Standard_EXPORT virtual void SetWindow (const Handle(Aspect_Window)&  theWindow,
+                                          const Aspect_RenderingContext theContext) Standard_OVERRIDE;
+
+  //! Returns window associated with the view.
+  virtual Handle(Aspect_Window) Window() const Standard_OVERRIDE { return myPlatformWindow; }
+
+  //! Returns True if the window associated to the view is defined.
+  virtual Standard_Boolean IsDefined() const Standard_OVERRIDE { return !myPlatformWindow.IsNull(); }
+
+  //! Handle changing size of the rendering window.
+  Standard_EXPORT virtual void Resized() Standard_OVERRIDE;
+
+  //! Redraw content of the view.
+  Standard_EXPORT virtual void Redraw() Standard_OVERRIDE;
+
+  //! Redraw immediate content of the view.
+  Standard_EXPORT virtual void RedrawImmediate() Standard_OVERRIDE;
+
+  //! Marks BVH tree for given priority list as dirty and marks primitive set for rebuild.
+  Standard_EXPORT virtual void Invalidate() Standard_OVERRIDE;
+
+  //! Return true if view content cache has been invalidated.
+  virtual Standard_Boolean IsInvalidated() Standard_OVERRIDE { return !myBackBufferRestored; }
+
+  //! Dump active rendering buffer into specified memory buffer.
+  //! In Ray-Tracing allow to get a raw HDR buffer using Graphic3d_BT_RGB_RayTraceHdrLeft buffer type,
+  //! only Left view will be dumped ignoring stereoscopic parameter.
+  Standard_EXPORT virtual Standard_Boolean BufferDump (Image_PixMap& theImage,
+                                                       const Graphic3d_BufferType& theBufferType) Standard_OVERRIDE;
+
+  //! Marks BVH tree and the set of BVH primitives of correspondent priority list with id theLayerId as outdated.
+  Standard_EXPORT virtual void InvalidateBVHData (const Graphic3d_ZLayerId theLayerId) Standard_OVERRIDE;
+
+  //! Insert a new top-level z layer with the given ID.
+  Standard_EXPORT virtual void AddZLayer (const Graphic3d_ZLayerId theLayerId) Standard_OVERRIDE;
+
+  //! Remove a z layer with the given ID.
+  Standard_EXPORT virtual void RemoveZLayer (const Graphic3d_ZLayerId theLayerId) Standard_OVERRIDE;
+
+  //! Sets the settings for a single Z layer of specified view.
+  Standard_EXPORT virtual void SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
+                                                  const Graphic3d_ZLayerSettings& theSettings) Standard_OVERRIDE;
+
+  //! Returns the maximum Z layer ID.
+  //! First layer ID is Graphic3d_ZLayerId_Default, last ID is ZLayerMax().
+  Standard_EXPORT virtual Standard_Integer ZLayerMax() const Standard_OVERRIDE;
+
+  //! Returns the bounding box of all structures displayed in the Z layer.
+  //! Never fails. If Z layer does not exist nothing happens.
+  Standard_EXPORT virtual void InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const Standard_OVERRIDE;
+
+  //! Returns the bounding box of all structures displayed in the Z layer.
+  //! If Z layer does not exist the empty box is returned.
+  //! @param theLayerId            layer identifier
+  //! @param theCamera             camera definition
+  //! @param theWindowWidth        viewport width  (for applying transformation-persistence)
+  //! @param theWindowHeight       viewport height (for applying transformation-persistence)
+  //! @param theToIncludeAuxiliary consider also auxiliary presentations (with infinite flag or with trihedron transformation persistence)
+  //! @return computed bounding box
+  Standard_EXPORT virtual Bnd_Box ZLayerBoundingBox (const Graphic3d_ZLayerId        theLayerId,
+                                                     const Handle(Graphic3d_Camera)& theCamera,
+                                                     const Standard_Integer          theWindowWidth,
+                                                     const Standard_Integer          theWindowHeight,
+                                                     const Standard_Boolean          theToIncludeAuxiliary) const Standard_OVERRIDE;
+
+  //! Returns pointer to an assigned framebuffer object.
+  Standard_EXPORT virtual Handle(Standard_Transient) FBO() const Standard_OVERRIDE;
+
+  //! Sets framebuffer object for offscreen rendering.
+  Standard_EXPORT virtual void SetFBO (const Handle(Standard_Transient)& theFbo) Standard_OVERRIDE;
+
+  //! Generate offscreen FBO in the graphic library.
+  //! If not supported on hardware returns NULL.
+  Standard_EXPORT virtual Handle(Standard_Transient) FBOCreate (const Standard_Integer theWidth,
+                                                                const Standard_Integer theHeight) Standard_OVERRIDE;
+
+  //! Remove offscreen FBO from the graphic library
+  Standard_EXPORT virtual void FBORelease (Handle(Standard_Transient)& theFbo) Standard_OVERRIDE;
+
+  //! Read offscreen FBO configuration.
+  Standard_EXPORT virtual void FBOGetDimensions (const Handle(Standard_Transient)& theFbo,
+                                                 Standard_Integer& theWidth,
+                                                 Standard_Integer& theHeight,
+                                                 Standard_Integer& theWidthMax,
+                                                 Standard_Integer& theHeightMax) Standard_OVERRIDE;
+
+  //! Change offscreen FBO viewport.
+  Standard_EXPORT virtual void FBOChangeViewport (const Handle(Standard_Transient)& theFbo,
+                                                  const Standard_Integer theWidth,
+                                                  const Standard_Integer theHeight) Standard_OVERRIDE;
+
+public:
+
+  //! Returns gradient background fill colors.
+  virtual Aspect_GradientBackground GradientBackground() const { return Aspect_GradientBackground(); }
+
+  //! Sets gradient background fill colors.
+  virtual void SetGradientBackground (const Aspect_GradientBackground& ) {}
+
+  //! Returns background image texture file path.
+  virtual TCollection_AsciiString BackgroundImage() Standard_OVERRIDE { return myBackgroundImagePath; }
+
+  //! Sets background image texture file path.
+  virtual void SetBackgroundImage (const TCollection_AsciiString& ) Standard_OVERRIDE {}
+
+  //! Returns background image fill style.
+  virtual Aspect_FillMethod BackgroundImageStyle() const Standard_OVERRIDE { return Aspect_FM_NONE; }
+
+  //! Sets background image fill style.
+  virtual void SetBackgroundImageStyle (const Aspect_FillMethod ) Standard_OVERRIDE {}
+
+  //! Returns environment texture set for the view.
+  virtual Handle(Graphic3d_TextureEnv) TextureEnv() const Standard_OVERRIDE { return myTextureEnvData; }
+
+  //! Sets environment texture for the view.
+  Standard_EXPORT virtual void SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv) Standard_OVERRIDE;
+
+  //! Return backfacing model used for the view.
+  virtual Graphic3d_TypeOfBackfacingModel BackfacingModel() const Standard_OVERRIDE { return myBackfacing; }
+
+  //! Sets backfacing model for the view.
+  virtual void SetBackfacingModel (const Graphic3d_TypeOfBackfacingModel theModel) Standard_OVERRIDE { myBackfacing = theModel; }
+
+  //! Returns local camera origin currently set for rendering, might be modified during rendering.
+  const gp_XYZ& LocalOrigin() const { return myLocalOrigin; }
+
+  //! Setup local camera origin currently set for rendering.
+  Standard_EXPORT void SetLocalOrigin (const gp_XYZ& theOrigin);
+
+  //! Returns list of lights of the view.
+  virtual const Handle(Graphic3d_LightSet)& Lights() const Standard_OVERRIDE { return myLights; }
+
+  //! Sets list of lights for the view.
+  virtual void SetLights (const Handle(Graphic3d_LightSet)& theLights) Standard_OVERRIDE
+  {
+    myLights = theLights;
+    ///myCurrLightSourceState = myStateCounter->Increment();
+  }
+
+  //! Returns list of clip planes set for the view.
+  virtual const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const Standard_OVERRIDE { return myClipPlanes; }
+
+  //! Sets list of clip planes for the view.
+  virtual void SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) Standard_OVERRIDE { myClipPlanes = thePlanes; }
+
+  //! Fill in the dictionary with diagnostic info.
+  //! Should be called within rendering thread.
+  //!
+  //! This API should be used only for user output or for creating automated reports.
+  //! The format of returned information (e.g. key-value layout)
+  //! is NOT part of this API and can be changed at any time.
+  //! Thus application should not parse returned information to weed out specific parameters.
+  Standard_EXPORT virtual void DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
+                                                      Graphic3d_DiagnosticInfo theFlags) const Standard_OVERRIDE;
+
+  //! Returns string with statistic performance info.
+  Standard_EXPORT virtual TCollection_AsciiString StatisticInformation() const Standard_OVERRIDE;
+
+  //! Fills in the dictionary with statistic performance info.
+  Standard_EXPORT virtual void StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const Standard_OVERRIDE;
+
+public:
+
+  //! Returns background color.
+  /**const Quantity_ColorRGBA& BackgroundColor() const { return myBgColor; }
+
+  void SetBackgroundTextureStyle (const Aspect_FillMethod FillStyle);
+
+  void SetBackgroundGradient (const Quantity_Color& AColor1, const Quantity_Color& AColor2, const Aspect_GradientFillMethod AType);
+
+  void SetBackgroundGradientType (const Aspect_GradientFillMethod AType);
+
+  //! Returns list of OpenGL Z-layers.
+  const OpenGl_LayerList& LayerList() const { return myZLayers; }
+
+  //! Returns OpenGL window implementation.
+  const Handle(OpenGl_Window)& GlWindow() const { return myWindow; }
+
+  //! Returns OpenGL environment map.
+  const Handle(OpenGl_TextureSet)& GlTextureEnv() const { return myTextureEnv; }
+
+  //! Returns selector for BVH tree, providing a possibility to store information
+  //! about current view volume and to detect which objects are overlapping it.
+  const OpenGl_BVHTreeSelector& BVHTreeSelector() const { return myBVHSelector; }
+
+  //! Returns true if there are immediate structures to display
+  bool HasImmediateStructures() const
+  {
+    return myZLayers.NbImmediateStructures() != 0;
+  }*/
+
+protected: //! @name low-level redrawing sub-routines
+
+  //! Redraws view for the given monographic camera projection, or left/right eye.
+ /** Standard_EXPORT virtual void redraw (const Graphic3d_Camera::Projection theProjection,
+                                       OpenGl_FrameBuffer*                theReadDrawFbo,
+                                       OpenGl_FrameBuffer*                theOitAccumFbo);
+
+  //! Redraws view for the given monographic camera projection, or left/right eye.
+  //!
+  //! Method will blit snapshot containing main scene (myMainSceneFbos or BackBuffer)
+  //! into presentation buffer (myMainSceneFbos -> offscreen FBO or
+  //! myMainSceneFbos -> BackBuffer or BackBuffer -> FrontBuffer),
+  //! and redraw immediate structures on top.
+  //!
+  //! When scene caching is disabled (myTransientDrawToFront, no double buffer in window, etc.),
+  //! the first step (blitting) will be skipped.
+  //!
+  //! @return false if immediate structures has been rendered directly into FrontBuffer
+  //! and Buffer Swap should not be called.
+  Standard_EXPORT virtual bool redrawImmediate (const Graphic3d_Camera::Projection theProjection,
+                                                OpenGl_FrameBuffer* theReadFbo,
+                                                OpenGl_FrameBuffer* theDrawFbo,
+                                                OpenGl_FrameBuffer* theOitAccumFbo,
+                                                const Standard_Boolean theIsPartialUpdate = Standard_False);
+
+  //! Blit image from/to specified buffers.
+  Standard_EXPORT bool blitBuffers (OpenGl_FrameBuffer*    theReadFbo,
+                                    OpenGl_FrameBuffer*    theDrawFbo,
+                                    const Standard_Boolean theToFlip = Standard_False);
+
+  //! Setup default FBO.
+  Standard_EXPORT void bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo = NULL);*/
+
+protected: //! @name Rendering of GL graphics (with prepared drawing buffer).
+
+  //! Renders the graphical contents of the view into the preprepared window or framebuffer.
+  //! @param theProjection [in] the projection that should be used for rendering.
+  //! @param theReadDrawFbo [in] the framebuffer for rendering graphics.
+  //! @param theOitAccumFbo [in] the framebuffer for accumulating color and coverage for OIT process.
+  //! @param theToDrawImmediate [in] the flag indicates whether the rendering performs in immediate mode.
+  /**Standard_EXPORT virtual void render (Graphic3d_Camera::Projection theProjection,
+                                       OpenGl_FrameBuffer*          theReadDrawFbo,
+                                       OpenGl_FrameBuffer*          theOitAccumFbo,
+                                       const Standard_Boolean       theToDrawImmediate);
+
+  //! Renders the graphical scene.
+  //! @param theProjection [in] the projection that is used for rendering.
+  //! @param theReadDrawFbo [in] the framebuffer for rendering graphics.
+  //! @param theOitAccumFbo [in] the framebuffer for accumulating color and coverage for OIT process.
+  //! @param theToDrawImmediate [in] the flag indicates whether the rendering performs in immediate mode.
+  Standard_EXPORT virtual void renderScene (Graphic3d_Camera::Projection theProjection,
+                                            OpenGl_FrameBuffer*    theReadDrawFbo,
+                                            OpenGl_FrameBuffer*    theOitAccumFbo,
+                                            const Standard_Boolean theToDrawImmediate);
+
+  //! Draw background (gradient / image)
+  Standard_EXPORT virtual void drawBackground (const Handle(OpenGl_Workspace)& theWorkspace);
+
+  //! Render set of structures presented in the view.
+  //! @param theProjection [in] the projection that is used for rendering.
+  //! @param theReadDrawFbo [in] the framebuffer for rendering graphics.
+  //! @param theOitAccumFbo [in] the framebuffer for accumulating color and coverage for OIT process.
+  //! @param theToDrawImmediate [in] the flag indicates whether the rendering performs in immediate mode.
+  Standard_EXPORT virtual void renderStructs (Graphic3d_Camera::Projection theProjection,
+                                              OpenGl_FrameBuffer*    theReadDrawFbo,
+                                              OpenGl_FrameBuffer*    theOitAccumFbo,
+                                              const Standard_Boolean theToDrawImmediate);*/
+
+private:
+
+  //! Initialize swapchain.
+  Standard_EXPORT bool initSwapChain (const Handle(Aspect_Window)& theWindow,
+                                      const Aspect_RenderingContext theContext);
+
+  //! Adds the structure to display lists of the view.
+  Standard_EXPORT virtual void displayStructure (const Handle(Graphic3d_CStructure)& theStructure,
+                                                 const Standard_Integer thePriority) Standard_OVERRIDE;
+
+  //! Erases the structure from display lists of the view.
+  Standard_EXPORT virtual void eraseStructure (const Handle(Graphic3d_CStructure)& theStructure) Standard_OVERRIDE;
+
+  //! Change Z layer of a structure already presented in view.
+  Standard_EXPORT virtual void changeZLayer (const Handle(Graphic3d_CStructure)& theCStructure,
+                                             const Graphic3d_ZLayerId theNewLayerId) Standard_OVERRIDE;
+
+  //! Changes the priority of a structure within its Z layer in the specified view.
+  Standard_EXPORT virtual void changePriority (const Handle(Graphic3d_CStructure)& theCStructure,
+                                               const Standard_Integer theNewPriority) Standard_OVERRIDE;
+
+  //! Returns zoom-scale factor.
+  Standard_EXPORT virtual Standard_Real considerZoomPersistenceObjects (const Graphic3d_ZLayerId        theLayerId,
+                                                                        const Handle(Graphic3d_Camera)& theCamera,
+                                                                        const Standard_Integer          theWindowWidth,
+                                                                        const Standard_Integer          theWindowHeight) const Standard_OVERRIDE;
+
+private:
+
+  //! Copy content of Back buffer to the Front buffer.
+  /**bool copyBackToFront();
+
+  //! Initialize blit quad.
+  OpenGl_VertexBuffer* initBlitQuad (const Standard_Boolean theToFlip);
+
+  //! Blend together views pair into stereo image.
+  void drawStereoPair (OpenGl_FrameBuffer* theDrawFbo);
+
+  //! Check and update OIT compatibility with current OpenGL context's state.
+  bool checkOitCompatibility (const Handle(OpenGl_Context)& theGlContext,
+                              const Standard_Boolean theMSAA);
+
+  //! Chooses compatible internal color format for OIT frame buffer.
+  bool chooseOitColorConfiguration (const Handle(OpenGl_Context)& theGlContext,
+                                    const Standard_Integer theConfigIndex,
+                                    OpenGl_ColorFormats& theFormats);*/
+
+protected:
+
+  Graphic3d_Layer myLayer; /// TODO
+  Standard_Integer       mySwapInterval;   //!< last assigned swap interval (VSync) for this window
+
+  Vulkan_GraphicDriver*    myDriver;
+  Handle(Vulkan_Context)   myContext;
+  Handle(Vulkan_Surface)   mySurface;
+  Handle(Aspect_Window)    myPlatformWindow; //!< software platform window wrapper
+  Standard_Boolean         myWasRedrawnGL;
+
+  Graphic3d_TypeOfBackfacingModel myBackfacing;
+  Handle(Graphic3d_SequenceOfHClipPlane) myClipPlanes;
+  gp_XYZ                          myLocalOrigin;
+  //Handle(OpenGl_FrameBuffer)      myFBO;
+  TCollection_AsciiString         myBackgroundImagePath;
+  Handle(Graphic3d_TextureEnv)    myTextureEnvData;
+
+  Handle(Graphic3d_LightSet)      myNoShadingLight;
+  Handle(Graphic3d_LightSet)      myLights;
+  ///OpenGl_LayerList                myZLayers; //!< main list of displayed structure, sorted by layers
+
+  Graphic3d_WorldViewProjState    myWorldViewProjState; //!< camera modification state
+  ///OpenGl_StateCounter*            myStateCounter;
+  ///Standard_Size                   myCurrLightSourceState;
+  ///Standard_Size                   myLightsRevision;
+
+  //typedef std::pair<Standard_Size, Standard_Size> StateInfo;
+  //StateInfo myLastOrientationState;
+  //StateInfo myLastViewMappingState;
+  //StateInfo myLastLightSourceState;
+
+  //! Is needed for selection of overlapping objects and storage of the current view volume
+  ///OpenGl_BVHTreeSelector myBVHSelector;
+
+  ///OpenGl_FrameStatsPrs      myFrameStatsPrs;
+
+  ///Handle(OpenGl_TextureSet) myTextureEnv;
+
+  //! Framebuffers for OpenGL output.
+  ///Handle(OpenGl_FrameBuffer) myOpenGlFBO;
+  ///Handle(OpenGl_FrameBuffer) myOpenGlFBO2;
+
+protected: //! @name Rendering properties
+
+  //! Two framebuffers (left and right views) store cached main presentation
+  //! of the view (without presentation of immediate layers).
+  int                        myFboColorFormat;        //!< sized format for color attachments
+  int                        myFboDepthFormat;        //!< sized format for depth-stencil attachments
+  //OpenGl_ColorFormats        myFboOitColorConfig;     //!< selected color format configuration for OIT color attachments
+  //Handle(OpenGl_FrameBuffer) myMainSceneFbos[2];
+  //Handle(OpenGl_FrameBuffer) myMainSceneFbosOit[2];      //!< Additional buffers for transparent draw of main layer.
+  //Handle(OpenGl_FrameBuffer) myImmediateSceneFbos[2];    //!< Additional buffers for immediate layer in stereo mode.
+  //Handle(OpenGl_FrameBuffer) myImmediateSceneFbosOit[2]; //!< Additional buffers for transparency draw of immediate layer.
+  ///OpenGl_VertexBuffer        myFullScreenQuad;        //!< Vertices for full-screen quad rendering.
+  ///OpenGl_VertexBuffer        myFullScreenQuadFlip;
+  ///Standard_Boolean           myToFlipOutput;          //!< Flag to draw result image upside-down
+  unsigned int               myFrameCounter;          //!< redraw counter, for debugging
+  Standard_Boolean           myHasFboBlit;            //!< disable FBOs on failure
+  Standard_Boolean           myToDisableOIT;          //!< disable OIT on failure
+  Standard_Boolean           myToDisableOITMSAA;      //!< disable OIT with MSAA on failure
+  Standard_Boolean           myToDisableMSAA;         //!< disable MSAA after failure
+  Standard_Boolean           myTransientDrawToFront; //!< optimization flag for immediate mode (to render directly to the front buffer)
+  Standard_Boolean           myBackBufferRestored;
+  Standard_Boolean           myIsImmediateDrawn;     //!< flag indicates that immediate mode buffer contains some data
+
+protected: //! @name Background parameters
+
+  ///OpenGl_Aspects*         myTextureParams;   //!< Stores texture and its parameters for textured background
+  ///OpenGl_BackgroundArray* myBgGradientArray; //!< Primitive array for gradient background
+  ///OpenGl_BackgroundArray* myBgTextureArray;  //!< Primitive array for texture  background
+
+};
+
+#endif // _Vulkan_View_HeaderFile
diff --git a/src/Vulkan/generate_spv.bat b/src/Vulkan/generate_spv.bat
new file mode 100644 (file)
index 0000000..282730e
--- /dev/null
@@ -0,0 +1,33 @@
+@echo off
+
+rem Auxiliary script compiling GLSL shaders into SPIR-V format.
+for %%i in (glslangValidator.exe) do ( if "%%~$PATH:i" == "" ( call "%~dp0../../env.bat" ) )
+for %%i in (glslangValidator.exe) do (
+  if "%%~$PATH:i" == "" (
+    echo "Error: could not find %%i"
+       exit /B
+  )
+)
+
+set "aClient=vulkan100"
+set "aDebug="
+rem set "aDebug=-g"
+
+rem Generate set of icons with standard resolutions.
+pushd "%~dp0"
+setlocal EnableDelayedExpansion
+for /r %%i in (*.vs) do (
+  set "aBase=%%~Ni"
+  set "aDst=!aBase!_vs_spv.pxx"
+  rem echo aBase=!aBase!
+  if exist "!aDst!" del "!aDst!"
+  glslangValidator.exe --client %aClient% %aDebug% -S vert "%%i" --vn "!aBase!_vs_spv" -o "!aDst!"
+)
+for /r %%i in (*.fs) do (
+  set "aBase=%%~Ni"
+  set "aDst=!aBase!_fs_spv.pxx"
+  rem echo aBase=!aBase!
+  if exist "!aDst!" del "!aDst!"
+  glslangValidator.exe --client %aClient% %aDebug% -S frag "%%i" --vn "!aBase!_fs_spv" -o "!aDst!"
+)
+popd