]> O.S.I.I.S - jp/vke.net.git/commitdiff
wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 19 Sep 2019 15:17:59 +0000 (17:17 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 19 Sep 2019 15:17:59 +0000 (17:17 +0200)
32 files changed:
README.md
SpirVTasks/CompileGLSLTask.cs
samples/DistanceFieldFontTest/Program.cs
samples/Model/main.cs
samples/Textured/main.cs
samples/TexturedCube/main.cs
samples/Triangle/README.md [new file with mode: 0644]
samples/Triangle/main.cs
samples/common/CrowWin.cs
samples/deferred/main.cs
samples/pbr/main.cs
vke/src/ExtensionMethods.cs
vke/src/FixedUtf8String.cs
vke/src/MarshaledObject.cs
vke/src/MemoryPool.cs
vke/src/PinnedObjects.cs [new file with mode: 0644]
vke/src/Utils.cs
vke/src/Version.cs [deleted file]
vke/src/VkWindow.cs
vke/src/base/CommandBuffer.cs
vke/src/base/DebugReport.cs
vke/src/base/DebugUtilsMessenger.cs
vke/src/base/DescriptorSetWrites.cs
vke/src/base/Device.cs
vke/src/base/Image.cs
vke/src/base/Instance.cs
vke/src/base/PhysicalDevice.cs
vke/src/base/Queue.cs
vke/src/glfw/CodePoint.cs
vke/src/glfw/Glfw3.cs
vke/src/ktx.cs
vke/vke.csproj

index 3f59e442dd32b206f2c12b748c7b098a1b952f2f..0dc9e047225c61f62aae97d9b9225ca70d593624 100644 (file)
--- a/README.md
+++ b/README.md
@@ -37,67 +37,3 @@ vke.net
 - ktx image loading.
 - Memory pools
 
-### VkWindow class
-
-To create a new vulkan application, derrive your application from `VkWindow`. Validation and
-debug reports may be activated with the static Fields of the `Instance` class.
-
-```csharp
-class Program : VkWindow {
-       static void Main (string[] args) {
-               Instance.VALIDATION = true;
-               
-               using (Program vke = new Program ()) {
-                       vke.Run ();
-               }
-       }
-}
-```
-
-### Enabling features
-
-Override the `configureEnabledFeatures` method of `VkWindow` to enable features.
-```csharp
-protected override void configureEnabledFeatures (VkPhysicalDeviceFeatures available_features, ref VkPhysicalDeviceFeatures enabled_features) {
-       enabled_features.samplerAnisotropy = available_features.samplerAnisotropy;
-}
-```
-### Creating queues
-
-To create queues, override the `createQueues` method of `VkWindow`. This function is called before the logical device creation and will take care of physically available queues, creating duplicates if count exceed availability. The `base` method will create a default presentable queue.
-
-```csharp
-protected override void createQueues () {
-       base.createQueues ();
-       transferQ = new Queue (dev, VkQueueFlags.Transfer);
-}
-```
-### Rendering
-
-The constructor of the `VkWIndow` will finish the vulkan initialisation, so that you may create pipelines, buffers, and so on in your constructor.
-
-VkWindow will provide the default swapchain, but it's up to you to create the frame buffers. For the triangle example, create them in the `OnResize` override.
-```csharp
-Framebuffer[] frameBuffers;
-
-protected override void OnResize () {
-       if (frameBuffers != null)
-               for (int i = 0; i < swapChain.ImageCount; ++i)
-                       frameBuffers[i]?.Dispose ();
-       frameBuffers = new Framebuffer[swapChain.ImageCount];
-
-       for (int i = 0; i < swapChain.ImageCount; ++i) 
-               frameBuffers[i] = new Framebuffer (pipeline.RenderPass, swapChain.Width, swapChain.Height,
-                       (pipeline.Samples == VkSampleCountFlags.SampleCount1) ? new Image[] {
-                               swapChain.images[i],
-                               null
-                       } : new Image[] {
-                               null,
-                               null,
-                               swapChain.images[i]
-                       });
-
-       buildCommandBuffers ();
-}
-```
-
index cac29fcd86a362e4510fd53b626dd647fd37c214..d6f074151d1c4aa7066268e81982e7da001a3335 100644 (file)
@@ -1,4 +1,8 @@
-using System;
+// Copyright (c) 2019  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+
+using System;
 using System.Diagnostics;
 using System.IO;
 using Microsoft.Build.Framework;
index 3c16773f7f6db2ee694bc0d511a6148bbba4386a..666a1d1b30a3303250095c591a6b05bae51983b0 100644 (file)
@@ -16,7 +16,6 @@ namespace DistanceFieldFontTest {
                        SwapChain.PREFERED_FORMAT = VkFormat.B8g8r8a8Unorm;
 #if DEBUG
                        Instance.VALIDATION = true;
-                       Instance.DEBUG_UTILS = true;
                        Instance.RENDER_DOC_CAPTURE = false;
 #endif
                        using (Program vke = new Program ()) {
index 9acc570b288e941e9024055b4e5cdc631cb50790..05bae06a65b558d35d481c4945ad5b7d4b4178ff 100644 (file)
@@ -13,7 +13,6 @@ namespace ModelSample
                static void Main (string[] args) {
 #if DEBUG
                        Instance.VALIDATION = true;
-                       Instance.DEBUG_UTILS = true;
                        Instance.RENDER_DOC_CAPTURE = false;
 #endif
                        using (Program vke = new Program ()) {
@@ -25,7 +24,6 @@ namespace ModelSample
                        public Matrix4x4 projection;
                        public Matrix4x4 view;
                        public Matrix4x4 model;
-                       //public Vector4 lightPos;
                }
 
                public struct PushConstants {
index 3cff23ca15c942e1a01529024fa1c4d97fe4b1b1..e78dea0cc1feec8b4906af763318575c7503ff94 100644 (file)
@@ -10,7 +10,6 @@ namespace Textured {
                static void Main (string[] args) {
 #if DEBUG
                        Instance.VALIDATION = true;
-                       Instance.DEBUG_UTILS = true;
                        Instance.RENDER_DOC_CAPTURE = true;
 #endif
 
index 8a3336a1d23161d175fafaed737ad5765b83cff7..db810c41e1c00e14dad07ab46c40c45ae163b362 100644 (file)
@@ -14,7 +14,6 @@ namespace TextureCube {
                static void Main (string[] args) {
 #if DEBUG
                        Instance.VALIDATION = true;
-                       Instance.DEBUG_UTILS = true;
                        Instance.RENDER_DOC_CAPTURE = false;
 #endif
                        using (Program vke = new Program ()) {
diff --git a/samples/Triangle/README.md b/samples/Triangle/README.md
new file mode 100644 (file)
index 0000000..35e3a72
--- /dev/null
@@ -0,0 +1,68 @@
+
+### VkWindow class
+
+To create a new vulkan application, derrive your application from `VkWindow`. Validation and
+debug reports may be activated with the static Fields of the `Instance` class.
+
+```csharp
+class Program : VkWindow {
+       static void Main (string[] args) {
+               Instance.VALIDATION = true;
+               
+               using (Program vke = new Program ()) {
+                       vke.Run ();
+               }
+       }
+}
+```
+### Enabling extensions
+
+The `VkWindow` class provides two properties that you may override to enable additional extensions.
+
+### Enabling features
+
+Override the `configureEnabledFeatures` method of `VkWindow` to enable features.
+```csharp
+protected override void configureEnabledFeatures (VkPhysicalDeviceFeatures available_features, ref VkPhysicalDeviceFeatures enabled_features) {
+       enabled_features.samplerAnisotropy = available_features.samplerAnisotropy;
+}
+```
+### Creating queues
+
+To create queues, override the `createQueues` method of `VkWindow`. This function is called before the logical device creation and will take care of physically available queues, creating duplicates if count exceed availability. The `base` method will create a default presentable queue.
+
+```csharp
+protected override void createQueues () {
+       base.createQueues ();
+       transferQ = new Queue (dev, VkQueueFlags.Transfer);
+}
+```
+### Rendering
+
+The constructor of the `VkWIndow` will finish the vulkan initialisation, so that you may create pipelines, buffers, and so on in your constructor.
+
+VkWindow will provide the default swapchain, but it's up to you to create the frame buffers. For the triangle example, create them in the `OnResize` override.
+```csharp
+Framebuffer[] frameBuffers;
+
+protected override void OnResize () {
+       if (frameBuffers != null)
+               for (int i = 0; i < swapChain.ImageCount; ++i)
+                       frameBuffers[i]?.Dispose ();
+       frameBuffers = new Framebuffer[swapChain.ImageCount];
+
+       for (int i = 0; i < swapChain.ImageCount; ++i) 
+               frameBuffers[i] = new Framebuffer (pipeline.RenderPass, swapChain.Width, swapChain.Height,
+                       (pipeline.Samples == VkSampleCountFlags.SampleCount1) ? new Image[] {
+                               swapChain.images[i],
+                               null
+                       } : new Image[] {
+                               null,
+                               null,
+                               swapChain.images[i]
+                       });
+
+       buildCommandBuffers ();
+}
+```
+
index 9addb88685a2c6084a4d7be46ba1c9d53222dc48..a9d5091fbde8584a5d6bb54953996f96dc289d28 100644 (file)
@@ -1,6 +1,7 @@
 // Copyright (c) 2019  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
 //
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
 using System.Numerics;
 using System.Runtime.InteropServices;
 using vke;
@@ -11,7 +12,6 @@ namespace Triangle {
                static void Main (string[] args) {
 #if DEBUG
                        Instance.VALIDATION = true;
-                       Instance.DEBUG_UTILS = true;
                        Instance.RENDER_DOC_CAPTURE = false;
 #endif
 
@@ -59,7 +59,6 @@ namespace Triangle {
                ushort[] indices = new ushort[] { 0, 1, 2 };
 
                Program () : base () {
-
                        cmds = cmdPool.AllocateCommandBuffer(swapChain.ImageCount);
 
                        vbo = new HostBuffer<Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
index cd440b083d2f03b16cd4b38c9a2dd5c390df4e6f..ee7b2ac53a11da2b0371026e6005bb20fb343ef1 100644 (file)
@@ -87,7 +87,7 @@ namespace Crow {
                }
 
                void crow_thread_func () {
-                       vkvgDev = new vkvg.Device (instance.Handle, phy.Handle, dev.Handle, presentQueue.qFamIndex,
+                       vkvgDev = new vkvg.Device (instance.Handle, phy.Handle, dev.VkDev.Handle, presentQueue.qFamIndex,
                                vkvg.SampleCount.Sample_4, presentQueue.index);
 
                        crow = new Interface (vkvgDev, (int)swapChain.Width, (int)swapChain.Height);
index b12d5204730b1ea4914e068728a0954f40bd165c..1130f75c36dc7b40bd227c5e2b5c88fbd8f6a88a 100644 (file)
@@ -11,7 +11,6 @@ namespace deferred {
                static void Main (string[] args) {
 #if DEBUG
                        Instance.VALIDATION = true;
-                       Instance.DEBUG_UTILS = true;
                        //Instance.RENDER_DOC_CAPTURE = false;
 #endif
                        SwapChain.PREFERED_FORMAT = VkFormat.B8g8r8a8Srgb;
@@ -27,6 +26,10 @@ namespace deferred {
                        }
                }
 
+               public override string[] EnabledInstanceExtensions => new string[] {
+                       Ext.I.VK_EXT_debug_utils
+               };
+
                public override string[] EnabledDeviceExtensions => new string[] {
                        Ext.D.VK_KHR_swapchain,
                        Ext.D.VK_EXT_debug_marker
@@ -75,9 +78,16 @@ namespace deferred {
                DescriptorPool descriptorPool;
                DescriptorSet descriptorSet;
 
+               vke.DebugUtils.Messenger dbgmsg;
+
+               Deferred () : base("deferred") {
+                       dbgmsg = new vke.DebugUtils.Messenger (instance, VkDebugUtilsMessageTypeFlagsEXT.PerformanceEXT | VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT | VkDebugUtilsMessageTypeFlagsEXT.GeneralEXT,
+                               VkDebugUtilsMessageSeverityFlagsEXT.InfoEXT |
+                               VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT |
+                               VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT |
+                               VkDebugUtilsMessageSeverityFlagsEXT.VerboseEXT);
 
 
-               Deferred () : base("deferred") {                
                        camera = new Camera (Utils.DegreesToRadians (45f), 1f, 0.1f, 16f);
                        camera.SetPosition (0, 0, 2);
 
@@ -512,6 +522,7 @@ namespace deferred {
                #endregion
 
                protected override void Dispose (bool disposing) {
+                       dev.WaitIdle ();
                        if (disposing) {
                                if (!isDisposed) {
                                        computeCmdPool.Dispose ();
@@ -522,6 +533,7 @@ namespace deferred {
                                        plBlur.Dispose ();
                                        plToneMap.Dispose ();
                                        descriptorPool.Dispose ();
+                                       dbgmsg.Dispose ();
                                }
                                dev.DestroySemaphore (blurComplete);
                        }
index 45ee433b0aef00ff7b9aa8b7c611b83283535f70..b3b84ee9c86bd435c2968a83d1d502026d677a3c 100644 (file)
@@ -18,7 +18,6 @@ namespace pbrSample {
                static void Main (string[] args) {
 #if DEBUG
                        Instance.VALIDATION = true;
-                       Instance.DEBUG_UTILS = true;
                        Instance.RENDER_DOC_CAPTURE = false;
 #endif
                        using (Program vke = new Program ()) {
index df7d5e6055f950de43f52477c6690a1d66bf12f5..afefdd9db8d0f1da6041acef267e7a9200615eae 100644 (file)
@@ -31,10 +31,22 @@ namespace vke {
                /// </summary>
                public static Dictionary<object, GCHandle> handles = new Dictionary<object, GCHandle>();
 
+               /// <summary>
+               /// Unpin the specified object and free the GCHandle associated.
+               /// </summary>
+               public static void Unpin (this object obj) {
+                       if (!handles.ContainsKey (obj)) {
+                               Debug.WriteLine ("Trying to unpin unpinned object: {0}.", obj);
+                               return;
+                       }
+                       handles[obj].Free ();
+                       handles.Remove (obj);
+               }
+
                /// <summary>
                /// Pin the specified object and return a pointer. MUST be Unpined as soon as possible.
                /// </summary>
-        public static IntPtr Pin (this object obj) {
+               public static IntPtr Pin (this object obj) {
                        if (handles.ContainsKey (obj)) {
                                Debug.WriteLine ("Trying to pin already pinned object: {0}", obj);
                                return handles[obj].AddrOfPinnedObject ();
@@ -43,17 +55,6 @@ namespace vke {
             GCHandle hnd = GCHandle.Alloc (obj, GCHandleType.Pinned);
             handles.Add (obj, hnd);
             return hnd.AddrOfPinnedObject ();
-        }
-               /// <summary>
-               /// Unpin the specified object and free the GCHandle associated.
-               /// </summary>
-        public static void Unpin (this object obj) {
-            if (!handles.ContainsKey (obj)) {
-                Debug.WriteLine ("Trying to unpin unpinned object: {0}.", obj);
-                return;
-            }
-            handles[obj].Free ();
-            handles.Remove (obj);
         }
         public static IntPtr Pin<T> (this List<T> obj) {
             if (handles.ContainsKey (obj)) 
@@ -81,6 +82,30 @@ namespace vke {
             handles.Add (obj, hnd);
             return hnd.AddrOfPinnedObject ();
         }
+
+               //pin with pinning context
+               public static IntPtr Pin (this object obj, PinnedObjects ctx) {
+                       GCHandle hnd = GCHandle.Alloc (obj, GCHandleType.Pinned);
+                       ctx.Handles.Add (hnd);
+                       return hnd.AddrOfPinnedObject ();
+               }
+               public static IntPtr Pin<T> (this List<T> obj, PinnedObjects ctx) {
+                       GCHandle hnd = GCHandle.Alloc (obj.ToArray (), GCHandleType.Pinned);
+                       ctx.Handles.Add (hnd);
+                       return hnd.AddrOfPinnedObject ();
+               }
+               public static IntPtr Pin<T> (this T[] obj, PinnedObjects ctx) {
+                       GCHandle hnd = GCHandle.Alloc (obj, GCHandleType.Pinned);
+                       ctx.Handles.Add (hnd);
+                       return hnd.AddrOfPinnedObject ();
+               }
+               public static IntPtr Pin (this string obj, PinnedObjects ctx) {
+                       byte[] n = System.Text.Encoding.UTF8.GetBytes (obj + '\0');
+                       GCHandle hnd = GCHandle.Alloc (n, GCHandleType.Pinned);
+                       ctx.Handles.Add (hnd);
+                       return hnd.AddrOfPinnedObject ();
+               }
+
                #endregion
 
                #region DebugMarkers
index 9d11cfd6294e66dbff094b00ee541b07b9fbe450..e8d9bb7de1cfc9e03f578a871396d160ae17e5a1 100644 (file)
@@ -2,78 +2,46 @@
 using System.Runtime.InteropServices;
 using System.Text;
 
-namespace Vulkan
-{
-    public class FixedUtf8String : IDisposable
-    {
-        GCHandle _handle;
-        uint _numBytes;
-
-        public IntPtr Ptr => _handle.AddrOfPinnedObject();
-
-        public FixedUtf8String(string s)
-        {
-            if (s == null)
-            {
-                throw new ArgumentNullException(nameof(s));
-            }
-
-            byte[] text = Encoding.UTF8.GetBytes(s + "\0");
-            _handle = GCHandle.Alloc(text, GCHandleType.Pinned);
-            _numBytes = (uint)text.Length;
-        }
-
-        public void SetText(string s)
-        {
-            if (s == null)
-            {
-                throw new ArgumentNullException(nameof(s));
-            }
-
-            _handle.Free();
-            byte[] text = Encoding.UTF8.GetBytes(s);
-            _handle = GCHandle.Alloc(text, GCHandleType.Pinned);
-            _numBytes = (uint)text.Length;
-        }
-
-        private string GetString()
-        {
-            return Marshal.PtrToStringUni(Ptr);
-        }
-        
-        public static implicit operator IntPtr (FixedUtf8String utf8String) => utf8String.Ptr;
-        public static implicit operator FixedUtf8String(string s) => new FixedUtf8String(s);
-        public static implicit operator string(FixedUtf8String utf8String) => utf8String.GetString();
-
-        #region IDisposable Support
-        private bool disposedValue = false; // Pour détecter les appels redondants
-
-        protected virtual void Dispose (bool disposing) {
-            if (!disposedValue) {
-                if (disposing) {
-                    // TODO: supprimer l'état managé (objets managés).
-                }
-
-                // TODO: libérer les ressources non managées (objets non managés) et remplacer un finaliseur ci-dessous.
-                // TODO: définir les champs de grande taille avec la valeur Null.
-                _handle.Free ();
-                disposedValue = true;
-            }
-        }
-
-        // TODO: remplacer un finaliseur seulement si la fonction Dispose(bool disposing) ci-dessus a du code pour libérer les ressources non managées.
-        ~FixedUtf8String() {
-          // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
-          Dispose(false);
-        }
-
-        // Ce code est ajouté pour implémenter correctement le modèle supprimable.
-        public void Dispose () {
-            // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
-            Dispose (true);
-            // TODO: supprimer les marques de commentaire pour la ligne suivante si le finaliseur est remplacé ci-dessus.
-             GC.SuppressFinalize(this);
-        }
-        #endregion
-    }
+namespace Vulkan {
+       public class FixedUtf8String : IDisposable {
+               GCHandle handle;
+               readonly uint numBytes;
+
+               public IntPtr Ptr => handle.AddrOfPinnedObject ();
+
+               public FixedUtf8String (string s) {
+                       if (s == null)
+                               throw new ArgumentNullException (nameof (s));
+
+                       byte[] text = Encoding.UTF8.GetBytes (s + "\0");
+                       handle = GCHandle.Alloc (text, GCHandleType.Pinned);
+                       numBytes = (uint)text.Length;
+               }
+
+               private string GetString () {
+                       return Marshal.PtrToStringUni (Ptr);
+               }
+
+               public static implicit operator IntPtr (FixedUtf8String utf8String) => utf8String.Ptr;
+               public static implicit operator FixedUtf8String (string s) => new FixedUtf8String (s);
+               public static implicit operator string (FixedUtf8String utf8String) => utf8String.GetString ();
+
+               #region IDisposable Support
+               private bool disposedValue = false; // Pour détecter les appels redondants
+
+               protected virtual void Dispose (bool disposing) {
+                       if (!disposedValue) {
+                               handle.Free ();
+                               disposedValue = true;
+                       }
+               }
+               ~FixedUtf8String () {
+                       Dispose (false);
+               }
+               public void Dispose () {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               #endregion
+       }
 }
\ No newline at end of file
index f6dd178e76ca6d4346ff941c7a0c9c33f45565e5..10cd344c22e7d46b88bc84ffbc2de9e14e85982a 100644 (file)
@@ -20,24 +20,12 @@ namespace vke {
         public MarshaledObject (T mobj) {
             handle = GCHandle.Alloc (mobj, GCHandleType.Pinned);
         }
-
-        void freeHandle () {
-            if (!disposed) 
-                handle.Free ();
-                       disposed = true;
+               ~MarshaledObject () {
+                       handle.Free ();
                }
-
-        #region IDisposable Support
-        private bool disposed;
-
-        ~MarshaledObject() {
-            freeHandle ();
-        }
-
-        public void Dispose () {
-            freeHandle ();
-            GC.SuppressFinalize(this);
-        }
-        #endregion
+               public void Dispose () {
+                       handle.Free ();
+                       GC.SuppressFinalize (this);
+               }        
     }
 }
index f3fc11b50bc727cbd8ec32e3408a55bf2dd6c2ac..492dd2f2d3e682a30ae48c2fd4ba611754675bc9 100644 (file)
@@ -8,9 +8,12 @@ using static Vulkan.Vk;
 
 namespace vke {
 #if MEMORY_POOLS
+       /// Direct how memory is allocated by a MemoryPool.
        public enum MemoryPoolType {
+               /// Not yet implemented.
                Random,
-               Linear 
+               /// First free space next to the last added ressource will be choosen.
+               Linear
        }
        /// <summary>
        /// A memory pool is a single chunck of memory of a kind shared among multiple resources.
@@ -19,34 +22,36 @@ namespace vke {
                Device dev;
                internal VkDeviceMemory vkMemory;
                VkMemoryAllocateInfo memInfo = VkMemoryAllocateInfo.New ();
-
-               //Resource firstResource;
+               readonly ulong bufferImageGranularity;
                Resource lastResource;
 
-               //Resource mappedFrom;
-               //Resource mappedTo;
-
-               //ulong freeMemPointer;
                IntPtr mappedPointer;
-
+               /// Allocated device size in byte.
                public ulong Size => memInfo.allocationSize;
+               /// Return true if pool memory is currently mapped.
                public bool IsMapped => mappedPointer != IntPtr.Zero;
+               /// Return mapped memory pointer or null if not mapped.
                public IntPtr MappedData => mappedPointer;
-               public Resource Last => lastResource;
+               /// Last added resource, this is the entry element for the double linked list of ressource.
+               public Resource Last => lastResource;                                                                   
 
                /// <summary>
-               /// Initializes a new instance of the <see cref="T:CVKL.MemoryPool"/> class.
+               /// Initializes a new instance of the <see cref="T:vke.MemoryPool"/> class.
                /// </summary>
-               /// <param name="dev">device</param>
+               /// <param name="dev">The vulkan device instance associated with this memory pool.</param>
                /// <param name="memoryTypeIndex">Memory type index.</param>
                /// <param name="size">Size</param>
                public MemoryPool (Device dev, uint memoryTypeIndex, UInt64 size) {
                        this.dev = dev;
+                       bufferImageGranularity = dev.phy.Limits.bufferImageGranularity;
                        memInfo.allocationSize = size;
                        memInfo.memoryTypeIndex = memoryTypeIndex;
                        Utils.CheckResult (vkAllocateMemory (dev.VkDev, ref memInfo, IntPtr.Zero, out vkMemory));
                }
-
+               /// <summary>
+               /// Allocate memory for a new resource in this memory pool.
+               /// </summary>
+               /// <param name="resource">An <see cref="T:vke.Image"/> or a <see cref="T:vke.Buffer"/> ressource.</param>
                public void Add (Resource resource) {
                        resource.memoryPool = this;
 
@@ -58,8 +63,8 @@ namespace vke {
                                do {
                                        offset = previous.poolOffset + previous.AllocatedDeviceMemorySize;
 
-                                       if (previous.IsLinar != resource.IsLinar && offset % dev.BufferImageGranularity > 0)
-                                               offset += dev.BufferImageGranularity - (offset % dev.BufferImageGranularity);
+                                       if (previous.IsLinar != resource.IsLinar && offset % bufferImageGranularity > 0)
+                                               offset += bufferImageGranularity - (offset % bufferImageGranularity);
                                        if (offset % resource.MemoryAlignment > 0)
                                                offset += resource.MemoryAlignment - (offset % resource.MemoryAlignment);
 
@@ -107,11 +112,16 @@ namespace vke {
 
                        resource.bindMemory ();
                }
-
+               /// <summary>
+               /// Try to reorganize ressources in this pool to optimize memory usage.
+               /// </summary>
                public void Defrag () {
                        throw new NotImplementedException ();
                }
-
+               /// <summary>
+               /// Remove the specified resource.
+               /// </summary>
+               /// <param name="resource">Resource.</param>
                public void Remove (Resource resource) {
                        if (resource == lastResource)
                                lastResource = resource.previous;
@@ -124,16 +134,23 @@ namespace vke {
                                }
                        }
                        resource.next = resource.previous = null;
-               }
+               }/// <summary>
+               /// Map the pool's memory at the specified offset.
+               /// </summary>
+               /// <param name="size">Size.</param>
+               /// <param name="offset">Offset.</param>
                public void Map (ulong size = Vk.WholeSize, ulong offset = 0) {
                        Utils.CheckResult (vkMapMemory (dev.VkDev, vkMemory, offset, size, 0, ref mappedPointer));
                }
+               /// <summary>
+               /// Unmap previously mapped memory of this pool.
+               /// </summary>
                public void Unmap () {
                        vkUnmapMemory (dev.VkDev, vkMemory);
                        mappedPointer = IntPtr.Zero;
                }
 
-#region IDisposable Support
+               #region IDisposable Support
                private bool disposedValue;
 
                protected virtual void Dispose (bool disposing) {
@@ -155,7 +172,7 @@ namespace vke {
                        Dispose (true);
                        GC.SuppressFinalize(this);
                }
-#endregion
+               #endregion
        }
 #endif
 }
\ No newline at end of file
diff --git a/vke/src/PinnedObjects.cs b/vke/src/PinnedObjects.cs
new file mode 100644 (file)
index 0000000..525a311
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright (c) 2019  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace vke {
+       /// <summary>
+       /// Keep pinned object gc handles and free them on dispose.
+       /// </summary>
+       public class PinnedObjects : IDisposable { 
+               public readonly List<GCHandle> Handles = new List<GCHandle> ();
+                       
+               public void Dispose () {
+                       for (int i = Handles.Count - 1; i >= 0; i--)
+                               Handles[i].Free ();
+                       GC.SuppressFinalize (this);
+               }
+       }
+}
index b2a3801ea86591eda5f4b7ac7521101582d86168..3cbd0395de51bb3909aac5858debfe73e2d54023 100644 (file)
@@ -285,6 +285,13 @@ namespace Vulkan {
                                        break;
                        }
                }
+               /// <summary>
+               /// Try to get the block width and height of a compressed format
+               /// </summary>
+               /// <returns><c>true</c>return true if format given as first argument is a compressed format.</returns>
+               /// <param name="format">Vulkan format to test.</param>
+               /// <param name="width">Compressed block width.</param>
+               /// <param name="height">Compressed block height.</param>
                public static bool TryGetCompressedFormatBlockSize (this VkFormat format, out uint width, out uint height)
                {
                        width = height = 1;
diff --git a/vke/src/Version.cs b/vke/src/Version.cs
deleted file mode 100644 (file)
index ed71d20..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace Vulkan 
-{
-    public struct Version
-    {
-        private readonly uint value;
-
-        public Version(uint major, uint minor, uint patch)
-        {
-            value = major << 22 | minor << 12 | patch;
-        }
-
-        public uint Major => value >> 22;
-
-        public uint Minor => (value >> 12) & 0x3ff;
-
-        public uint Patch => (value >> 22) & 0xfff;
-
-        public static implicit operator uint(Version version)
-        {
-            return version.value;
-        }
-    }
-}
\ No newline at end of file
index 6d8ceb07f1924330126c220aef441abfbeb78aea..fc40cb477cecc76c4785065bdf5c9d8e44fdb3da 100644 (file)
@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
+using System.Runtime.InteropServices;
 using Glfw;
 using Vulkan;
 using static Vulkan.Vk;
@@ -18,10 +19,12 @@ namespace vke {
                static Dictionary<IntPtr,VkWindow> windows = new Dictionary<IntPtr, VkWindow>();
 
                IntPtr hWin;
-
+               /**Vulkan Surface */
                protected VkSurfaceKHR hSurf;
-               protected Instance instance;
-               protected PhysicalDevice phy;
+               /**vke Instance encapsulating a VkInstance. */
+               protected Instance instance;    
+               /**vke Physical device associated with this window*/
+               protected PhysicalDevice phy;   
                protected Device dev;
                protected PresentQueue presentQueue;
                protected SwapChain swapChain;
@@ -29,8 +32,6 @@ namespace vke {
                protected CommandBuffer[] cmds;
                protected VkSemaphore[] drawComplete;
 
-               DebugReport dbgRepport;
-
                protected uint fps;
                protected bool updateViewRequested = true;
                protected double lastMouseX, lastMouseY;
@@ -48,7 +49,12 @@ namespace vke {
                Stopwatch frameChrono;
 
                /// <summary>
-               /// Override this property to change the list of enabled extensions
+               /// Override this property to change the list of enabled instance extensions
+               /// </summary>
+               public virtual string[] EnabledInstanceExtensions => null;
+
+               /// <summary>
+               /// Override this property to change the list of enabled device extensions
                /// </summary>
                public virtual string[] EnabledDeviceExtensions => new string[] { Ext.D.VK_KHR_swapchain };
 
@@ -100,22 +106,17 @@ namespace vke {
                }
 
                void initVulkan (bool vSync) {
-                       instance = new Instance ();
-
-                       if (Instance.DEBUG_UTILS) {
-                               //dbgmsg = new CVKL.DebugUtils.Messenger (instance);
-                               dbgRepport = new DebugReport (instance,
-                                       VkDebugReportFlagsEXT.ErrorEXT
-                                       | VkDebugReportFlagsEXT.WarningEXT
-                                       | VkDebugReportFlagsEXT.PerformanceWarningEXT
-                               );
-                       }
+                       List<string> instExts = new List<string> (Glfw3.GetRequiredInstanceExtensions ());
+                       if (EnabledInstanceExtensions != null)
+                               instExts.AddRange (EnabledInstanceExtensions);
+
+                       instance = new Instance (instExts.ToArray());
 
                        hSurf = instance.CreateSurface (hWin);
 
-                       phy = instance.GetAvailablePhysicalDevice ().Where (p => p.HasSwapChainSupport).FirstOrDefault ();
+                       phy = instance.GetAvailablePhysicalDevice ().FirstOrDefault (p => p.HasSwapChainSupport);
 
-                       VkPhysicalDeviceFeatures enabledFeatures = default (VkPhysicalDeviceFeatures);
+                       VkPhysicalDeviceFeatures enabledFeatures = default;
                        configureEnabledFeatures (phy.Features, ref enabledFeatures);
 
                        //First create the c# device class
@@ -146,13 +147,14 @@ namespace vke {
                        cmdPool.SetName ("main CmdPool");
                }
                /// <summary>
-               /// override this method to modify enabled features before device creation
+               /// Override this method to modify enabled features before device creation. Feature availability is given by the first argument.
                /// </summary>
-               /// <param name="enabled_features">Features.</param>
+               /// <param name="available_features">Available features for the selected vulkan physical device associated with this window</param>
+               /// <param name="enabled_features">Set boolean fileds of this structure to true to enable features.</param>
                protected virtual void configureEnabledFeatures (VkPhysicalDeviceFeatures available_features, ref VkPhysicalDeviceFeatures enabled_features) {
                }
                /// <summary>
-               /// override this method to create additional queue. Dedicated queue of the requested type will be selected first, created queues may excess
+               /// Override this method to create additional queue. Dedicated queue of the requested type will be selected first, created queues may excess
                /// available physical queues.
                /// </summary>
                protected virtual void createQueues () {
@@ -333,7 +335,6 @@ namespace vke {
                                if (disposing) {
                                        cmdPool.Dispose ();
                                        dev.Dispose ();
-                                       dbgRepport?.Dispose ();
                                        instance.Dispose ();
                                } else
                                        Debug.WriteLine ("a VkWindow has not been correctly disposed");
index 220a565f6875b9912fd8b4323dba135d9844bc04..83e2f9bd1e22625adf034efdfa8ae950a8985baa 100644 (file)
@@ -41,27 +41,22 @@ namespace vke {
                        IntPtr dstStageMask = Marshal.AllocHGlobal (sizeof(uint));
                        Marshal.WriteInt32 (dstStageMask, (int)VkPipelineStageFlags.ColorAttachmentOutput);
 
-            submit_info.pWaitDstStageMask = dstStageMask;
-            if (signal != VkSemaphore.Null) {
-                submit_info.signalSemaphoreCount = 1;
-                submit_info.pSignalSemaphores = signal.Pin();
-            }
-            if (wait != VkSemaphore.Null) {
-                submit_info.waitSemaphoreCount = 1;
-                submit_info.pWaitSemaphores = wait.Pin();
-            }
-
-            submit_info.commandBufferCount = 1;
-            submit_info.pCommandBuffers = handle.Pin();
-
-            Utils.CheckResult (vkQueueSubmit (queue, 1, ref submit_info, fence));
-
-                       if (signal != VkSemaphore.Null)
-                               signal.Unpin ();
-                       if (wait != VkSemaphore.Null)
-                               wait.Unpin ();
-                       handle.Unpin ();
-
+                       using (PinnedObjects pctx = new PinnedObjects ()) {
+                               submit_info.pWaitDstStageMask = dstStageMask;
+                               if (signal != VkSemaphore.Null) {
+                                       submit_info.signalSemaphoreCount = 1;
+                                       submit_info.pSignalSemaphores = signal.Pin (pctx);
+                               }
+                               if (wait != VkSemaphore.Null) {
+                                       submit_info.waitSemaphoreCount = 1;
+                                       submit_info.pWaitSemaphores = wait.Pin (pctx);
+                               }
+
+                               submit_info.commandBufferCount = 1;
+                               submit_info.pCommandBuffers = handle.Pin (pctx);
+
+                               Utils.CheckResult (vkQueueSubmit (queue, 1, ref submit_info, fence));
+                       }
                        Marshal.FreeHGlobal (dstStageMask);
         }
         public void Start (VkCommandBufferUsageFlags usage = 0) {
index 1e1842bdb93c2f0811e1f067b859e9d643b98f0c..e5e8e8880b1c407d0d1e4fabbfe247a3f781202c 100644 (file)
@@ -1,35 +1,13 @@
-//
-// DebugReport.cs
+// Copyright (c) 2019  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
 //
-// Author:
-//       Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// Copyright (c) 2019 jp
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 using System;
 using System.Runtime.InteropServices;
 using Vulkan;
 using static Vulkan.Vk;
 
 namespace vke {
-
+       [Obsolete("Use the new VK_EXT_debug_utils extension")]
     public class DebugReport : IDisposable {        
         VkDebugReportCallbackEXT handle;
                Instance inst;
index 9a8339242eae7fdf6738e05047167ba215ff1aba..419e14056f0f260a7f7d4739fd1adfbcdc1a72ad 100644 (file)
@@ -4,68 +4,80 @@ using Vulkan;
 using static Vulkan.Vk;
 
 namespace vke.DebugUtils {
-
-    public class Messenger : IDisposable {
+       /// <summary>
+       /// Dispoable vke class that encapsulate a VkDebugUtilsMessengerEXT object
+       /// </summary>
+       public class Messenger : IDisposable {
                Instance inst;
-               VkDebugUtilsMessengerEXT handle;
-               PFN_vkDebugUtilsMessengerCallbackEXT onMessage = new PFN_vkDebugUtilsMessengerCallbackEXT(HandlePFN_vkDebugUtilsMessengerCallbackEXT);
+               readonly VkDebugUtilsMessengerEXT handle;
+               readonly static PFN_vkDebugUtilsMessengerCallbackEXT onMessage = new PFN_vkDebugUtilsMessengerCallbackEXT(HandlePFN_vkDebugUtilsMessengerCallbackEXT);
 
                static VkBool32 HandlePFN_vkDebugUtilsMessengerCallbackEXT (VkDebugUtilsMessageSeverityFlagsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, IntPtr pCallbackData, IntPtr pUserData) {
-                       //Console.WriteLine ("{0} {1}: {2}",messageSeverity, messageTypes, Marshal.PtrToStringAnsi(pUserData));
-                       Console.WriteLine ("MESSAGE RECEIVED");
-                       return false;
-               }
-
-
-
-   //     PFN_vkDebugReportCallbackEXT debugCallbackDelegate = new PFN_vkDebugReportCallbackEXT (debugCallback);
+                       VkDebugUtilsMessengerCallbackDataEXT data = Marshal.PtrToStructure<VkDebugUtilsMessengerCallbackDataEXT> (pCallbackData);
+                       ConsoleColor curColor = Console.ForegroundColor;
 
-   //     static VkBool32 debugCallback (VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, ulong obj,
-   //         UIntPtr location, int messageCode, IntPtr pLayerPrefix, IntPtr pMessage, IntPtr pUserData) {
-   //         string prefix = "";
-   //         switch (flags) {
-   //             case 0:
-   //                 prefix = "?";
-   //                 break;
-   //             case VkDebugReportFlagsEXT.InformationEXT:
-                       //              Console.ForegroundColor = ConsoleColor.Gray;
-                       //              prefix = "INFO";
-   //                 break;
-   //             case VkDebugReportFlagsEXT.WarningEXT:
-                       //              Console.ForegroundColor = ConsoleColor.DarkYellow;
-                       //              prefix = "WARN";
-   //                 break;
-   //             case VkDebugReportFlagsEXT.PerformanceWarningEXT:
-                       //              Console.ForegroundColor = ConsoleColor.Yellow;
-                       //              prefix = "PERF";
-   //                 break;
-   //             case VkDebugReportFlagsEXT.ErrorEXT:
-                       //              Console.ForegroundColor = ConsoleColor.DarkRed;
-                       //              prefix = "EROR";
-                       //              break;
-   //             case VkDebugReportFlagsEXT.DebugEXT:
-                       //              Console.ForegroundColor = ConsoleColor.Red;
-                       //              prefix = "DBUG";
-   //                 break;
-   //         }
+                       switch (messageSeverity) {
+                       case VkDebugUtilsMessageSeverityFlagsEXT.VerboseEXT:
+                               Console.ForegroundColor = ConsoleColor.White;
+                               break;
+                       case VkDebugUtilsMessageSeverityFlagsEXT.InfoEXT:
+                               Console.ForegroundColor = ConsoleColor.DarkCyan;
+                               break;
+                       case VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT:
+                               Console.ForegroundColor = ConsoleColor.DarkYellow;
+                               break;
+                       case VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT:
+                               Console.ForegroundColor = ConsoleColor.Red;
+                               break;
+                       }
 
-   //         Console.WriteLine ("{0} {1}: {2}",prefix, messageCode, Marshal.PtrToStringAnsi(pMessage));
-                       //Console.ForegroundColor = ConsoleColor.White;
-        //    return VkBool32.False;
-        //}
-        
-        public Messenger (Instance instance,
-               VkDebugUtilsMessageTypeFlagsEXT typeMask =  VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT,
-                       VkDebugUtilsMessageSeverityFlagsEXT severityMask = VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT | VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT) {
+                       switch (messageTypes) {
+                       case VkDebugUtilsMessageTypeFlagsEXT.GeneralEXT:
+                               Console.Write ("GEN:");
+                               break;
+                       case VkDebugUtilsMessageTypeFlagsEXT.PerformanceEXT:
+                               Console.Write ("PERF:");
+                               break;                  
+                       }
 
+                       Console.WriteLine (Marshal.PtrToStringAnsi (data.pMessage));
+                       Console.ForegroundColor = curColor;
+                       return false;
+               }
+               /// <summary>
+               /// Create a new debug utils messenger providing a PFN_vkDebugUtilsMessengerCallbackEXT delegate.
+               /// </summary>
+               /// <param name="instance">Vulkan Instance.</param>
+               /// <param name="onMessageDelegate">Message callback.</param>
+               /// <param name="typeMask">Type mask.</param>
+               /// <param name="severityMask">Severity mask.</param>
+               public Messenger (Instance instance, PFN_vkDebugUtilsMessengerCallbackEXT onMessageDelegate,
+                       VkDebugUtilsMessageTypeFlagsEXT typeMask =
+                               VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT,
+                       VkDebugUtilsMessageSeverityFlagsEXT severityMask =
+                               VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT |
+                               VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT) {
                        inst = instance;
                        VkDebugUtilsMessengerCreateInfoEXT info = VkDebugUtilsMessengerCreateInfoEXT.New ();
                        info.messageType = typeMask;
                        info.messageSeverity = severityMask;
-                       info.pfnUserCallback = Marshal.GetFunctionPointerForDelegate (onMessage);
+                       info.pfnUserCallback = Marshal.GetFunctionPointerForDelegate (onMessageDelegate);
                        info.pUserData = IntPtr.Zero;
 
                        Utils.CheckResult (vkCreateDebugUtilsMessengerEXT (inst.VkInstance, ref info, IntPtr.Zero, out handle));
+               }
+               /// <summary>
+               /// Create a new debug utils messenger with default message callback outputing to Console.
+               /// </summary>
+               /// <param name="instance">Vulkan Instance.</param>
+               /// <param name="typeMask">Type mask.</param>
+               /// <param name="severityMask">Severity mask.</param>
+               public Messenger (Instance instance,
+                       VkDebugUtilsMessageTypeFlagsEXT typeMask =
+                               VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT,
+                       VkDebugUtilsMessageSeverityFlagsEXT severityMask =
+                               VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT |
+                               VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT) : this (instance, onMessage, typeMask, severityMask) {
         }
 
                #region IDisposable Support
index 51f8c0a967d10a1a173bad154cd0fff6c190e6d6..227ea0d6b58cdedb751f008e355e318b683ab4a1 100644 (file)
@@ -121,47 +121,76 @@ namespace vke {
                /// execute the descriptors writes targeting descriptorSets setted on AddWriteInfo call
                /// </summary>
                public void Write (Device dev, params object[] descriptors) {
-                       //if (descriptors.Length != WriteDescriptorSets.Count)
-                       //      throw new Exception ("descriptors count must equal the WriteInfo count.");
-                       List<object> descriptorsLists = new List<object> ();//strore temp arrays of pDesc for unpinning
-                                                                                                                               //if descriptorCount>1
-                       int i = 0;
-                       int wdsPtr = 0;
-                       while (i < descriptors.Length) {
-                               int firstDescriptor = i;
-                               VkWriteDescriptorSet wds = WriteDescriptorSets[wdsPtr];
-                               if (dstSetOverride != null)
-                                       wds.dstSet = dstSetOverride.Value.Handle;
-                               IntPtr pDescriptors = IntPtr.Zero;
+                       using (PinnedObjects pinCtx = new PinnedObjects ()) {
+                               int i = 0;
+                               int wdsPtr = 0;
+                               while (i < descriptors.Length) {
+                                       int firstDescriptor = i;
+                                       VkWriteDescriptorSet wds = WriteDescriptorSets[wdsPtr];
+                                       if (dstSetOverride != null)
+                                               wds.dstSet = dstSetOverride.Value.Handle;
+                                       IntPtr pDescriptors = IntPtr.Zero;
 
-                               if (wds.descriptorCount > 1) {
-                                       List<IntPtr> descPtrArray = new List<IntPtr> ();
-                                       for (int d = 0; d < wds.descriptorCount; d++) {
-                                               descPtrArray.Add (descriptors[i].Pin ());
+                                       if (wds.descriptorCount > 1) {
+                                               List<IntPtr> descPtrArray = new List<IntPtr> ();
+                                               for (int d = 0; d < wds.descriptorCount; d++) {
+                                                       descPtrArray.Add (descriptors[i].Pin (pinCtx));
+                                                       i++;
+                                               }
+                                               pDescriptors = descPtrArray.Pin (pinCtx);
+                                       } else {
+                                               pDescriptors = descriptors[i].Pin (pinCtx);
                                                i++;
                                        }
-                                       descriptorsLists.Add (descPtrArray);
-                                       pDescriptors = descPtrArray.Pin ();
-                               } else {
-                                       pDescriptors = descriptors[i].Pin ();
-                                       i++;
+                                       if (descriptors[firstDescriptor] is VkDescriptorBufferInfo)
+                                               wds.pBufferInfo = pDescriptors;
+                                       else if (descriptors[firstDescriptor] is VkDescriptorImageInfo)
+                                               wds.pImageInfo = pDescriptors;
+
+                                       WriteDescriptorSets[wdsPtr] = wds;
+                                       wdsPtr++;
                                }
-                               if (descriptors[firstDescriptor] is VkDescriptorBufferInfo)
-                                       wds.pBufferInfo = pDescriptors;
-                               else if (descriptors[firstDescriptor] is VkDescriptorImageInfo)
-                                       wds.pImageInfo = pDescriptors;
+                               vkUpdateDescriptorSets (dev.VkDev, (uint)WriteDescriptorSets.Count, WriteDescriptorSets.Pin (pinCtx), 0, IntPtr.Zero);
+                       }                       
+               }
+               /// <summary>
+               /// execute the descriptors writes targeting descriptorSets setted on AddWriteInfo call
+               /// </summary>
+               public void Push (CommandBuffer cmd, PipelineLayout plLayout, params object[] descriptors) {
+                       using (PinnedObjects pinCtx = new PinnedObjects ()) {
+                               int i = 0;
+                               int wdsPtr = 0;
+                               while (i < descriptors.Length) {
+                                       int firstDescriptor = i;
+                                       VkWriteDescriptorSet wds = WriteDescriptorSets[wdsPtr];
+                                       wds.dstSet = 0;
+                                       IntPtr pDescriptors = IntPtr.Zero;
 
-                               WriteDescriptorSets[wdsPtr] = wds;
-                               wdsPtr++;
+                                       if (wds.descriptorCount > 1) {
+                                               List<IntPtr> descPtrArray = new List<IntPtr> ();
+                                               for (int d = 0; d < wds.descriptorCount; d++) {
+                                                       descPtrArray.Add (descriptors[i].Pin (pinCtx));
+                                                       i++;
+                                               }
+                                               pDescriptors = descPtrArray.Pin (pinCtx);
+                                       } else {
+                                               pDescriptors = descriptors[i].Pin (pinCtx);
+                                               i++;
+                                       }
+                                       if (descriptors[firstDescriptor] is VkDescriptorBufferInfo)
+                                               wds.pBufferInfo = pDescriptors;
+                                       else if (descriptors[firstDescriptor] is VkDescriptorImageInfo)
+                                               wds.pImageInfo = pDescriptors;
+
+                                       WriteDescriptorSets[wdsPtr] = wds;
+                                       wdsPtr++;
+                               }
+                               vkCmdPushDescriptorSetKHR (cmd.Handle, VkPipelineBindPoint.Graphics, plLayout.handle, 0,
+                                        (uint)WriteDescriptorSets.Count, WriteDescriptorSets.Pin (pinCtx));
                        }
-                       vkUpdateDescriptorSets (dev.VkDev, (uint)WriteDescriptorSets.Count, WriteDescriptorSets.Pin (), 0, IntPtr.Zero);
-                       WriteDescriptorSets.Unpin ();
-                       foreach (object descArray in descriptorsLists) 
-                               descArray.Unpin ();
-                       for (i = 0; i < descriptors.Length; i++) 
-                               descriptors[i].Unpin ();                        
                }
        }
+
        /// <summary>
        /// Descriptor set writes include descriptor in write addition with IDisposable model
        /// </summary>
index 8f61fe97c9ee78b33ebeac351b39a5ca61c3c558..a9256250313c0239fee17968482407c6044bfb50 100644 (file)
@@ -1,30 +1,7 @@
-//
-// Device.cs
+// Copyright (c) 2019  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
 //
-// Author:
-//       Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// Copyright (c) 2019 jp
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
@@ -40,12 +17,11 @@ namespace vke {
        /// after being disposed.
        /// </summary>
        public class Device : IDisposable {
-               public readonly PhysicalDevice phy;
+               public readonly PhysicalDevice phy;                                                                             /**Vulkan physical device class*/
 
                VkDevice dev;
-               public VkDevice VkDev => dev;
-               public IntPtr Handle => dev.Handle;
-               public readonly ulong BufferImageGranularity;
+               public VkDevice VkDev => dev;                                           /**Vulkan logical device handle*/               
+
 
                internal List<Queue> queues = new List<Queue> ();
                internal bool debugMarkersEnabled;
@@ -56,7 +32,6 @@ namespace vke {
 
                public Device (PhysicalDevice _phy) {
                        phy = _phy;
-                       BufferImageGranularity = phy.Limits.bufferImageGranularity;
                }
 
                public void Activate (VkPhysicalDeviceFeatures enabledFeatures, params string[] extensions) {
index 7b6d000539cb78a79162683ed4b730400aba4ec8..5238fa7dff957e7095afe3a01c23f4a59959193d 100644 (file)
@@ -555,7 +555,7 @@ namespace vke {
                 case VkImageLayout.TransferSrcOptimal:
                     // Image will be used as a transfer source
                     // Make sure any reads from and writes to the image have been finished
-                    imageMemoryBarrier.srcAccessMask |= VkAccessFlags.TransferRead;
+                    //imageMemoryBarrier.srcAccessMask |= VkAccessFlags.TransferRead;
                     imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferRead;
                     break;
 
index 86e303bbdfcc3ff1174cb4a17c312b2fde90476f..71e9c9d417c8c58377d2cbd1831c73e1dd72ffa8 100644 (file)
@@ -25,6 +25,7 @@
 // THE SOFTWARE.
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Runtime.InteropServices;
 using Vulkan;
 using static Vulkan.Vk;
@@ -33,119 +34,99 @@ namespace vke {
        /// <summary>
        /// Vulkan Instance disposable class
        /// </summary>
-    public class Instance : IDisposable {
+       public class Instance : IDisposable {
                /// <summary>If true, the VK_LAYER_KHRONOS_validation layer is loaded at startup; </summary>
                public static bool VALIDATION;
-               /// <summary>If true, the VK_EXT_debug_utils and VK_EXT_debug_report instance extensions are enabled</summary>
-               public static bool DEBUG_UTILS;
                /// <summary>If true, the VK_LAYER_RENDERDOC_Capture layer is loaded at startup; </summary>
                public static bool RENDER_DOC_CAPTURE;
 
-        VkInstance inst;
+               public static uint VK_MAJOR = 1;
+               public static uint VK_MINOR = 1;
+
+               public static string ENGINE_NAME = "vke.net";
+               public static string APPLICATION_NAME = "vke.net";
+
+               VkInstance inst;
 
                public IntPtr Handle => inst.Handle;
                public VkInstance VkInstance => inst;
 
 
                static class Strings {
-            public static FixedUtf8String Name = "VKENGINE";
-            public static FixedUtf8String VK_KHR_SURFACE_EXTENSION_NAME = "VK_KHR_surface";
-            public static FixedUtf8String VK_KHR_WIN32_SURFACE_EXTENSION_NAME = "VK_KHR_win32_surface";
-            public static FixedUtf8String VK_KHR_XCB_SURFACE_EXTENSION_NAME = "VK_KHR_xcb_surface";
-            public static FixedUtf8String VK_KHR_XLIB_SURFACE_EXTENSION_NAME = "VK_KHR_xlib_surface";
-            public static FixedUtf8String VK_KHR_SWAPCHAIN_EXTENSION_NAME = "VK_KHR_swapchain";
-            public static FixedUtf8String VK_EXT_DEBUG_REPORT_EXTENSION_NAME = "VK_EXT_debug_report";
-                       public static FixedUtf8String VK_EXT_DEBUG_UTILS_EXTENSION_NAME = "VK_EXT_debug_utils";
-                       public static FixedUtf8String LayerValidation = "VK_LAYER_KHRONOS_validation";
-                       public static FixedUtf8String LayerValidation_old = "VK_LAYER_LUNARG_standard_validation"; 
-                       public static FixedUtf8String LayerMonitor = "VK_LAYER_LUNARG_monitor";
-                       public static FixedUtf8String VkTraceLayeName = "VK_LAYER_LUNARG_vktrace";
-            public static FixedUtf8String RenderdocCaptureLayerName = "VK_LAYER_RENDERDOC_Capture";
-            public static FixedUtf8String main = "main";
-        }        
-
-        public Instance () {
-            init ();
-        }
-
-               unsafe bool ExtensionIsSupported (FixedUtf8String layer, string extName) {
-                       uint count;
-                       Utils.CheckResult (vkEnumerateInstanceExtensionProperties ((IntPtr)layer, out count, IntPtr.Zero));
-                       VkExtensionProperties[] tmp = new VkExtensionProperties[count];
-                       Utils.CheckResult (vkEnumerateInstanceExtensionProperties (layer, out count, tmp.Pin ()));
-                       tmp.Unpin ();
-
-                       fixed (VkExtensionProperties* ep = tmp) {
-                               for (int i = 0; i < tmp.Length; i++) {
-                                       IntPtr n = (IntPtr)ep[i].extensionName;
-                                       if (Marshal.PtrToStringAnsi (n) == extName)
-                                                       return true;
-                               }
-                       }
-                       return false;
-               }
-
 
+                       public static FixedUtf8String main = "main";
+               }
+               const string strValidationLayer = "VK_LAYER_KHRONOS_validation";
+               const string strRenderDocLayer = "VK_LAYER_RENDERDOC_Capture";
 
-               void init () {
+               /// <summary>
+               /// Create a new vulkan instance with enabled extensions given as argument.
+               /// </summary>
+               /// <param name="extensions">List of extension to enable if supported</param>
+               public Instance (params string[] extensions) {
                        List<IntPtr> instanceExtensions = new List<IntPtr> ();
                        List<IntPtr> enabledLayerNames = new List<IntPtr> ();
 
-                       instanceExtensions.Add (Strings.VK_KHR_SURFACE_EXTENSION_NAME);
-                       if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
-                               instanceExtensions.Add (Strings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
-                       } else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
-                               instanceExtensions.Add (Strings.VK_KHR_XCB_SURFACE_EXTENSION_NAME);
-                       } else {
-                               throw new PlatformNotSupportedException ();
-                       }
-
-                       if (VALIDATION) {
-                               enabledLayerNames.Add (Strings.LayerValidation);
-                               //enabledLayerNames.Add (Strings.LayerValidation_old);
+                       string[] supportedExts = SupportedExtensions (IntPtr.Zero);
 
-                               if (DEBUG_UTILS) {
-                                       //if (ExtensionIsSupported(Strings.LayerValidation, Strings.VK_EXT_DEBUG_UTILS_EXTENSION_NAME))
-                                       //instanceExtensions.Add (Strings.VK_EXT_DEBUG_UTILS_EXTENSION_NAME);                                           
-                                       instanceExtensions.Add (Strings.VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
+                       using (PinnedObjects pctx = new PinnedObjects ()) {
+                               for (int i = 0; i < extensions.Length; i++) {
+                                       if (supportedExts.Contains (extensions[i]))
+                                               instanceExtensions.Add (extensions[i].Pin (pctx));
+                                       else
+                                               Console.WriteLine ($"Vulkan initialisation: Unsupported extension: {extensions[i]}");
                                }
 
-                       }
-                       if (RENDER_DOC_CAPTURE)
-                               enabledLayerNames.Add (Strings.RenderdocCaptureLayerName);
 
+                               if (VALIDATION) 
+                                       enabledLayerNames.Add (strValidationLayer.Pin (pctx));
+                               if (RENDER_DOC_CAPTURE)
+                                       enabledLayerNames.Add (strRenderDocLayer.Pin (pctx));
 
-                       VkApplicationInfo appInfo = new VkApplicationInfo () {
-                               sType = VkStructureType.ApplicationInfo,
-                               apiVersion = new Vulkan.Version (1, 0, 0),
-                               pApplicationName = Strings.Name,
-                               pEngineName = Strings.Name,
-                       };
 
-                       VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo.New ();
-                       instanceCreateInfo.pApplicationInfo = appInfo.Pin ();
+                               VkApplicationInfo appInfo = new VkApplicationInfo () {
+                                       sType = VkStructureType.ApplicationInfo,
+                                       apiVersion = new Vulkan.Version (VK_MAJOR, VK_MINOR, 0),
+                                       pApplicationName = ENGINE_NAME.Pin (pctx),
+                                       pEngineName = APPLICATION_NAME.Pin (pctx),
+                               };
 
-                       if (instanceExtensions.Count > 0) {
-                               instanceCreateInfo.enabledExtensionCount = (uint)instanceExtensions.Count;
-                               instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.Pin ();
-                       }
-                       if (enabledLayerNames.Count > 0) {
-                               instanceCreateInfo.enabledLayerCount = (uint)enabledLayerNames.Count;
-                               instanceCreateInfo.ppEnabledLayerNames = enabledLayerNames.Pin ();
+                               VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo.New ();
+                               instanceCreateInfo.pApplicationInfo = appInfo.Pin (pctx);
+
+                               if (instanceExtensions.Count > 0) {
+                                       instanceCreateInfo.enabledExtensionCount = (uint)instanceExtensions.Count;
+                                       instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.Pin (pctx);
+                               }
+                               if (enabledLayerNames.Count > 0) {
+                                       instanceCreateInfo.enabledLayerCount = (uint)enabledLayerNames.Count;
+                                       instanceCreateInfo.ppEnabledLayerNames = enabledLayerNames.Pin (pctx);
+                               }
+
+                               VkResult result = vkCreateInstance (ref instanceCreateInfo, IntPtr.Zero, out inst);
+                               if (result != VkResult.Success)
+                                       throw new InvalidOperationException ("Could not create Vulkan instance. Error: " + result);
+
+                               Vk.LoadInstanceFunctionPointers (inst);
                        }
+               }
 
-                       VkResult result = vkCreateInstance (ref instanceCreateInfo, IntPtr.Zero, out inst);
-                       if (result != VkResult.Success)
-                               throw new InvalidOperationException ("Could not create Vulkan instance. Error: " + result);
+               public string[] SupportedExtensions (IntPtr layer) {
+                       Utils.CheckResult (vkEnumerateInstanceExtensionProperties (layer, out uint count, IntPtr.Zero));
 
-                       Vk.LoadInstanceFunctionPointers (inst);
+                       int sizeStruct = Marshal.SizeOf<VkExtensionProperties> ();
+                       IntPtr ptrSupExts = Marshal.AllocHGlobal (sizeStruct * (int)count);
+                       Utils.CheckResult (vkEnumerateInstanceExtensionProperties (layer, out count, ptrSupExts));
 
-                       appInfo.Unpin ();
+                       string[] result = new string[count];
+                       IntPtr tmp = ptrSupExts;
+                       for (int i = 0; i < count; i++) {
+                               result[i] = Marshal.PtrToStringAnsi (tmp);
+                               tmp += sizeStruct;
+                       }
 
-                       if (instanceExtensions.Count > 0)
-                               instanceExtensions.Unpin ();
-                       if (enabledLayerNames.Count > 0)
-                               enabledLayerNames.Unpin ();
+                       Marshal.FreeHGlobal (ptrSupExts);
+                       return result;
                }
 
                public PhysicalDeviceCollection GetAvailablePhysicalDevice () => new PhysicalDeviceCollection (inst);
@@ -158,35 +139,35 @@ namespace vke {
                        return surf;
                }
                public void GetDelegate<T> (string name, out T del) {
-            using (FixedUtf8String n = new FixedUtf8String (name)) {
-                del = Marshal.GetDelegateForFunctionPointer<T> (vkGetInstanceProcAddr (Handle, (IntPtr)n));
-            }
-        }
+                       using (FixedUtf8String n = new FixedUtf8String (name)) {
+                               del = Marshal.GetDelegateForFunctionPointer<T> (vkGetInstanceProcAddr (Handle, (IntPtr)n));
+                       }
+               }
 
-        #region IDisposable Support
-        private bool disposedValue = false;
+               #region IDisposable Support
+               private bool disposedValue = false;
 
-        protected virtual void Dispose (bool disposing) {
-            if (!disposedValue) {
+               protected virtual void Dispose (bool disposing) {
+                       if (!disposedValue) {
                                if (disposing) {
                                        // TODO: supprimer l'état managé (objets managés).
                                } else
                                        System.Diagnostics.Debug.WriteLine ("Instance disposed by Finalizer");
-                
-                vkDestroyInstance (inst, IntPtr.Zero);
-
-                disposedValue = true;
-            }
-        }
-
-        ~Instance () {
-           Dispose(false);
-        }
-
-        public void Dispose () {
-            Dispose (true);
-            GC.SuppressFinalize(this);
-        }
-        #endregion
-    }
+
+                               vkDestroyInstance (inst, IntPtr.Zero);
+
+                               disposedValue = true;
+                       }
+               }
+
+               ~Instance () {
+                       Dispose (false);
+               }
+
+               public void Dispose () {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               #endregion
+       }
 }
index 82e258268b5ada41d0cc7bda1c14a84dd868efcc..c82e20eda22c6ff9088e94949eb38f0b51131f27 100644 (file)
@@ -1,28 +1,6 @@
-//
-// PhysicalDevice.cs
+// Copyright (c) 2019  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
 //
-// Author:
-//       Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// Copyright (c) 2019 jp
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 using System;
 using Vulkan;
 using static Vulkan.Vk;
@@ -30,66 +8,58 @@ using static Vulkan.Utils;
 using System.Collections;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
-
 using System.Linq;
 
 namespace vke {
-    public class PhysicalDeviceCollection : IEnumerable<PhysicalDevice> {
-        VkInstance inst;
-        PhysicalDevice[] phys;
-
+       /// <summary>
+       /// Collection of physical devices returned by the vulkan instance.
+       /// </summary>
+       public class PhysicalDeviceCollection : IEnumerable<PhysicalDevice> {
+        readonly VkInstance inst;
+        readonly PhysicalDevice[] phys;
+
+               /// <summary>
+               /// Retrieve the physical devices available for the provided vulkan instance
+               /// </summary>
+               /// <param name="instance">The vulkan instance to retrieve the physical devices from.</param>
         public PhysicalDeviceCollection (VkInstance instance) {
             inst = instance;
-            init ();
-        }
+                       CheckResult (vkEnumeratePhysicalDevices (inst, out uint gpuCount, IntPtr.Zero));
+                       if (gpuCount <= 0)
+                               throw new Exception ("No GPU found");
 
-        public PhysicalDevice this[int i] {
-            get {
-                return phys[i];
-            }
-        }
-
-        public IEnumerator<PhysicalDevice> GetEnumerator () {
-            return ((IEnumerable<PhysicalDevice>)phys).GetEnumerator ();
-        }
+                       IntPtr gpus = Marshal.AllocHGlobal (Marshal.SizeOf<IntPtr> () * (int)gpuCount);
+                       CheckResult (vkEnumeratePhysicalDevices (inst, out gpuCount, gpus), "Could not enumerate physical devices.");
 
-        IEnumerator IEnumerable.GetEnumerator () {
-            return ((IEnumerable<PhysicalDevice>)phys).GetEnumerator ();
-        }
-
-        void init () {
-            uint gpuCount = 0;
-            CheckResult (vkEnumeratePhysicalDevices (inst, out gpuCount, IntPtr.Zero));
-            if (gpuCount <= 0)
-                throw new Exception ("No GPU found");
-
-                       IntPtr gpus = Marshal.AllocHGlobal (Marshal.SizeOf<IntPtr> ()* (int)gpuCount); 
-            CheckResult (vkEnumeratePhysicalDevices (inst, out gpuCount, gpus), "Could not enumerate physical devices.");
-            
-            phys = new PhysicalDevice[gpuCount];
+                       phys = new PhysicalDevice[gpuCount];
 
-            for (int i = 0; i < gpuCount; i++)
-                phys[i] = new PhysicalDevice (Marshal.ReadIntPtr(gpus + i * Marshal.SizeOf<IntPtr>()));
+                       for (int i = 0; i < gpuCount; i++)
+                               phys[i] = new PhysicalDevice (Marshal.ReadIntPtr (gpus + i * Marshal.SizeOf<IntPtr> ()));
 
                        Marshal.FreeHGlobal (gpus);
-        }
+               }
+
+        public PhysicalDevice this[int i] => phys[i];
+        public IEnumerator<PhysicalDevice> GetEnumerator () => ((IEnumerable<PhysicalDevice>)phys).GetEnumerator ();
+        IEnumerator IEnumerable.GetEnumerator () => ((IEnumerable<PhysicalDevice>)phys).GetEnumerator ();
     }
+       /// <summary>
+       /// Vke class that encapsulate a physical device.
+       /// </summary>
     public class PhysicalDevice {
-        IntPtr phy;
+        readonly IntPtr phy;
 
         public VkPhysicalDeviceMemoryProperties memoryProperties { get; private set; }
         public VkQueueFamilyProperties[] QueueFamilies { get; private set; }
                public VkPhysicalDeviceProperties Properties {
                        get {
-                               VkPhysicalDeviceProperties pdp;
-                               vkGetPhysicalDeviceProperties (phy, out pdp);
+                               vkGetPhysicalDeviceProperties (phy, out VkPhysicalDeviceProperties pdp);
                                return pdp;
                        }
                }
                public VkPhysicalDeviceFeatures Features {
                        get {
-                               VkPhysicalDeviceFeatures df;
-                               vkGetPhysicalDeviceFeatures (phy, out df);
+                               vkGetPhysicalDeviceFeatures (phy, out VkPhysicalDeviceFeatures df);
                                return df;
                        }
                }
@@ -97,88 +67,60 @@ namespace vke {
 
         public bool HasSwapChainSupport { get; private set; }
         public IntPtr Handle => phy;
+               public bool GetDeviceExtensionSupported (string extName) => SupportedExtensions (IntPtr.Zero).Contains (extName);
 
-        public PhysicalDevice (IntPtr vkPhy) {
+               #region CTOR
+               internal PhysicalDevice (IntPtr vkPhy) {
             phy = vkPhy;
-            init ();
-        }
 
-        unsafe void init () {
-            // Gather physical Device memory properties
-            IntPtr tmp = Marshal.AllocHGlobal (Marshal.SizeOf<VkPhysicalDeviceMemoryProperties>());
-            vkGetPhysicalDeviceMemoryProperties (phy, tmp);
-            memoryProperties = Marshal.PtrToStructure<VkPhysicalDeviceMemoryProperties> (tmp);
+                       // Gather physical Device memory properties
+                       IntPtr tmp = Marshal.AllocHGlobal (Marshal.SizeOf<VkPhysicalDeviceMemoryProperties> ());
+                       vkGetPhysicalDeviceMemoryProperties (phy, tmp);
+                       memoryProperties = Marshal.PtrToStructure<VkPhysicalDeviceMemoryProperties> (tmp);
 
-            uint queueFamilyCount = 0;
-            vkGetPhysicalDeviceQueueFamilyProperties (phy, out queueFamilyCount, IntPtr.Zero);
-            QueueFamilies = new VkQueueFamilyProperties[queueFamilyCount];
+                       vkGetPhysicalDeviceQueueFamilyProperties (phy, out uint queueFamilyCount, IntPtr.Zero);
+                       QueueFamilies = new VkQueueFamilyProperties[queueFamilyCount];
 
-            if (queueFamilyCount <= 0)
-                throw new Exception ("No queues found for physical device");
+                       if (queueFamilyCount <= 0)
+                               throw new Exception ("No queues found for physical device");
 
                        vkGetPhysicalDeviceQueueFamilyProperties (phy, out queueFamilyCount, QueueFamilies.Pin ());
                        QueueFamilies.Unpin ();
 
-            uint propCount = 0;
-
-            vkEnumerateDeviceExtensionProperties (phy, IntPtr.Zero, out propCount, IntPtr.Zero);
-
-            VkExtensionProperties[] extProps = new VkExtensionProperties[propCount];
-
-                       vkEnumerateDeviceExtensionProperties (phy, IntPtr.Zero, out propCount, extProps.Pin ());
-                       extProps.Unpin ();
-
-            for (int i = 0; i < extProps.Length; i++)
-            {
-                fixed (VkExtensionProperties* ep = extProps) {
-                    IntPtr n = (IntPtr)ep[i].extensionName;
-                    switch (Marshal.PtrToStringAnsi(n))
-                    {
-                        case "VK_KHR_swapchain":
-                            HasSwapChainSupport = true;
-                            break;
-                    }
-                }
-                       }               
-        }
-
-               public unsafe bool GetDeviceExtensionSupported (string extName) {
-                       uint propCount = 0;
-
-                       vkEnumerateDeviceExtensionProperties (phy, IntPtr.Zero, out propCount, IntPtr.Zero);
+                       HasSwapChainSupport = GetDeviceExtensionSupported (Ext.D.VK_KHR_swapchain);
+               }
+               #endregion
 
-                       VkExtensionProperties[] extProps = new VkExtensionProperties[propCount];
+               public string[] SupportedExtensions (IntPtr layer) {
+                       CheckResult (vkEnumerateDeviceExtensionProperties (phy, layer, out uint count, IntPtr.Zero));
 
-                       vkEnumerateDeviceExtensionProperties (phy, IntPtr.Zero, out propCount, extProps.Pin ());
-                       extProps.Unpin ();
+                       int sizeStruct = Marshal.SizeOf<VkExtensionProperties> ();
+                       IntPtr ptrSupExts = Marshal.AllocHGlobal (sizeStruct * (int)count);
+                       CheckResult (vkEnumerateDeviceExtensionProperties (phy, layer, out count, ptrSupExts));
 
-                       for (int i = 0; i < extProps.Length; i++) {
-                               fixed (VkExtensionProperties* ep = extProps) {
-                                       IntPtr n = (IntPtr)ep[i].extensionName;
-                                       if (Marshal.PtrToStringAnsi (n) == extName)
-                                                       return true;
-                               }
+                       string[] result = new string[count];
+                       IntPtr tmp = ptrSupExts;
+                       for (int i = 0; i < count; i++) {
+                               result[i] = Marshal.PtrToStringAnsi (tmp);
+                               tmp += sizeStruct;
                        }
-                       Console.WriteLine ($"INFO: unsuported device extension: {extName}");
-                       return false;
-               }
 
+                       Marshal.FreeHGlobal (ptrSupExts);
+                       return result;
+               }
 
-        public bool GetPresentIsSupported (uint qFamilyIndex, VkSurfaceKHR surf) {
-            VkBool32 isSupported = false;
-            vkGetPhysicalDeviceSurfaceSupportKHR (phy, qFamilyIndex, surf, out isSupported);
+        public bool GetPresentIsSupported (uint qFamilyIndex, VkSurfaceKHR surf) {             
+            vkGetPhysicalDeviceSurfaceSupportKHR (phy, qFamilyIndex, surf, out VkBool32 isSupported);
             return isSupported;
         }
 
-        public VkSurfaceCapabilitiesKHR GetSurfaceCapabilities (VkSurfaceKHR surf) {
-            VkSurfaceCapabilitiesKHR caps;
-            vkGetPhysicalDeviceSurfaceCapabilitiesKHR (phy, surf, out caps);
+        public VkSurfaceCapabilitiesKHR GetSurfaceCapabilities (VkSurfaceKHR surf) {            
+            vkGetPhysicalDeviceSurfaceCapabilitiesKHR (phy, surf, out VkSurfaceCapabilitiesKHR caps);
             return caps;
         }
 
-        unsafe public VkSurfaceFormatKHR[] GetSurfaceFormats (VkSurfaceKHR surf) {
-            uint count = 0;
-            vkGetPhysicalDeviceSurfaceFormatsKHR (phy, surf, out count, IntPtr.Zero);
+        public VkSurfaceFormatKHR[] GetSurfaceFormats (VkSurfaceKHR surf) {            
+            vkGetPhysicalDeviceSurfaceFormatsKHR (phy, surf, out uint count, IntPtr.Zero);
             VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[count];
             
             vkGetPhysicalDeviceSurfaceFormatsKHR (phy, surf, out count, formats.Pin());
@@ -186,9 +128,8 @@ namespace vke {
             
             return formats;
         }
-        unsafe public VkPresentModeKHR[] GetSurfacePresentModes (VkSurfaceKHR surf) {
-            uint count = 0;
-            vkGetPhysicalDeviceSurfacePresentModesKHR (phy, surf, out count, IntPtr.Zero);
+        public VkPresentModeKHR[] GetSurfacePresentModes (VkSurfaceKHR surf) {            
+            vkGetPhysicalDeviceSurfacePresentModesKHR (phy, surf, out uint count, IntPtr.Zero);
             VkPresentModeKHR[] modes = new VkPresentModeKHR[count];
             
             vkGetPhysicalDeviceSurfacePresentModesKHR (phy, surf, out count, modes.Pin());
@@ -196,9 +137,8 @@ namespace vke {
             
             return modes;
         }
-        public VkFormatProperties GetFormatProperties (VkFormat format) {
-            VkFormatProperties properties;
-            vkGetPhysicalDeviceFormatProperties (phy, format, out properties);
+        public VkFormatProperties GetFormatProperties (VkFormat format) {            
+            vkGetPhysicalDeviceFormatProperties (phy, format, out VkFormatProperties properties);
             return properties;
         }
     }
index 1dddfa0bc46fe90f4eb468e8ac0f1c25d513a28d..6c3bad82a6c3f125f6957357ce783806dbe77849 100644 (file)
@@ -1,30 +1,7 @@
-//
-// Queue.cs
+// Copyright (c) 2019  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
 //
-// Author:
-//       Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// Copyright (c) 2019 jp
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 using System;
-using System.Collections;
 using Vulkan;
 
 using static Vulkan.Vk;
index 09a60c9630931a958b072b843e634a26aad4d4a7..a081e9f8a06f2d69c2e5a3eb0bc770660a92d6cc 100644 (file)
@@ -27,7 +27,7 @@ namespace Glfw
                /// <returns>
                /// The character representation of the codepoint.
                /// </returns>
-               public char ToChar() => Encoding.UTF32.GetChars (new byte[] { byte0, byte0, byte0, byte0 })[0];
+               public char ToChar() => Encoding.UTF32.GetChars (new byte[] { byte0, byte1, byte2, byte3 })[0];
         /// <summary>
         /// Converts the value of this instance to its equivalent string representation.
         /// </summary>
index 1531d79ba49f0fe0efc0f7c407bc1d32d9930157..081ec5c598e23fe441bb97877056eb787245a78c 100644 (file)
@@ -452,11 +452,11 @@ namespace Glfw {
         {
             IntPtr names = GetRequiredInstanceExtensions(out int count);
 
-            var result = new string[count];
+            string[] result = new string[count];
 
             for (int nameIndex = 0; nameIndex < count; nameIndex++)
             {
-                               IntPtr name = Marshal.ReadIntPtr (names, nameIndex);
+                               IntPtr name = Marshal.ReadIntPtr (names, nameIndex * Marshal.SizeOf<IntPtr>());
                 result[nameIndex] = Marshal.PtrToStringAnsi(name);
             }
 
index ce6948fa921b6c5f14b23e13bd3f02cb58e04062..5baa7d13c678aea5e754c18c2427799a87a48abb 100644 (file)
@@ -2,12 +2,11 @@
 //
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 using System;
+using System.Collections.Generic;
 using System.IO;
-
-using Vulkan;
-using vke;
 using System.Runtime.InteropServices;
-using System.Collections.Generic;
+using vke;
+using Vulkan;
 
 namespace KTX {
 
index ca13eff4b69150b30670e12898f96a2533db2ccc..7e4158a4c96c293b35b07f3fc5f18eefb0121ab0 100644 (file)
@@ -26,6 +26,8 @@
                
                <EnableDefaultNoneItems>false</EnableDefaultNoneItems>          
     <LangVersion>7.2</LangVersion>
+               <GenerateDocumentationFile>true</GenerateDocumentationFile>    
+               <NoWarn>$(NoWarn);1591</NoWarn>
        </PropertyGroup>
        
        <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@@ -47,7 +49,7 @@
                
        <ItemGroup>
                <PackageReference Include="SpirVTasks" Version="0.1.10-beta" />
-               <PackageReference Include="Vulkan" Version="0.1.6-beta" />
+               <PackageReference Include="Vulkan" Version="0.1.7" />
        </ItemGroup>
        <ItemGroup>
                <GLSLShader Include="shaders\**\*.frag;shaders\**\*.vert;shaders\**\*.comp;shaders\**\*.geom">