diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2019-05-04 06:28:23 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2019-05-04 06:28:23 +0200 |
| commit | 4c6ab111878cd182218c10d62ec47eb180cc4197 (patch) | |
| tree | e3b838f183954e5353df42669959e78ae0cceac7 | |
| parent | 1c46bcec119e279e5d35b45912bf728e71acc197 (diff) | |
replace NativeList<T> with Pin/Unpin extension methods
| -rw-r--r-- | samples/deferred/main.cs | 8 | ||||
| -rw-r--r-- | vk.net.sln | 2 | ||||
| -rw-r--r-- | vke/CVKL.csproj | 4 | ||||
| -rw-r--r-- | vke/src/CommandPool.cs | 25 | ||||
| -rw-r--r-- | vke/src/DescriptorPool.cs | 7 | ||||
| -rw-r--r-- | vke/src/Device.cs | 10 | ||||
| -rw-r--r-- | vke/src/ExtensionMethods.cs | 10 | ||||
| -rw-r--r-- | vke/src/Instance.cs | 46 | ||||
| -rw-r--r-- | vke/src/NativeList.cs | 546 | ||||
| -rw-r--r-- | vke/src/PhysicalDevice.cs | 16 | ||||
| -rw-r--r-- | vke/src/RenderPass.cs | 5 | ||||
| -rw-r--r-- | vke/src/SubPass.cs | 139 | ||||
| -rw-r--r-- | vke/src/ktx.cs | 95 |
13 files changed, 194 insertions, 719 deletions
diff --git a/samples/deferred/main.cs b/samples/deferred/main.cs index 7493c0c..5e67801 100644 --- a/samples/deferred/main.cs +++ b/samples/deferred/main.cs @@ -70,17 +70,9 @@ namespace deferred { crow = new Crow.Interface (vkvgDev, 800, 600); isRunning = true; - //int frameCount = 0; while (isRunning) { crow.Update (); - - /*if (frameCount++ > 100) { - for (int i = 0; i < crow.PerfMeasures.Count; i++) - crow.PerfMeasures[i].NotifyChanges (); - frameCount = 0; - }*/ - Thread.Sleep (2); } @@ -15,7 +15,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SachaWillemPbr", "samples\p EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vkvg_tests", "samples\vkvg_tests\vkvg_tests.csproj", "{1F05E74F-AEE8-481C-8FDF-456654CC30BE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vulkan-netcore", "VK\vulkan.csproj", "{1603D809-D9C4-4EE5-B921-B053CE22E068}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vulkan", "VK\vulkan.csproj", "{1603D809-D9C4-4EE5-B921-B053CE22E068}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CVKL", "vke\CVKL.csproj", "{9E12DFE6-7DC7-4BF2-8077-42DDC69FD0A1}" EndProject diff --git a/vke/CVKL.csproj b/vke/CVKL.csproj index 9023ab9..8f91af2 100644 --- a/vke/CVKL.csproj +++ b/vke/CVKL.csproj @@ -41,13 +41,9 @@ <Reference Include="System" /> <Reference Include="System.Runtime" /> <Reference Include="System.Core" /> - <Reference Include="System.Runtime.CompilerServices.Unsafe"> - <HintPath>..\..\..\..\..\usr\lib\monodevelop\bin\System.Runtime.CompilerServices.Unsafe.dll</HintPath> - </Reference> </ItemGroup> <ItemGroup Condition="$(TargetFramework.StartsWith('netstandard'))"> <PackageReference Include="System.Numerics.Vectors" Version="4.6.0-preview4.19212.13" /> - <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2" /> </ItemGroup> <ItemGroup> <PackageReference Include="glTF2Loader" Version="1.1.3-alpha" /> diff --git a/vke/src/CommandPool.cs b/vke/src/CommandPool.cs index 4d21d4e..d89ee7e 100644 --- a/vke/src/CommandPool.cs +++ b/vke/src/CommandPool.cs @@ -94,18 +94,19 @@ namespace CVKL { vkFreeCommandBuffers (Dev.VkDev, handle, 1, ref hnd); return; } - using (NativeList<VkCommandBuffer> nlCmds = new NativeList<VkCommandBuffer> ((uint)cmds.Length, (uint)cmds.Length)) { - int count = 0; - for (int i = 0; i < cmds.Length; i++) { - if (cmds[i] == null) - continue; - nlCmds[count] = cmds[i].Handle; - count++; - } - if (count == 0) - return; - vkFreeCommandBuffers (Dev.VkDev, handle, (uint)count, nlCmds.Data); - } + int sizeElt = Marshal.SizeOf<IntPtr> (); + IntPtr cmdsPtr = Marshal.AllocHGlobal (cmds.Length * sizeElt); + int count = 0; + for (int i = 0; i < cmds.Length; i++) { + if (cmds[i] == null) + continue; + Marshal.WriteIntPtr (cmdsPtr + count * sizeElt, cmds[i].Handle.Handle); + count++; + } + if (count > 0) + vkFreeCommandBuffers (Dev.VkDev, handle, (uint)count, cmdsPtr); + + Marshal.FreeHGlobal (cmdsPtr); } public override string ToString () { diff --git a/vke/src/DescriptorPool.cs b/vke/src/DescriptorPool.cs index bd5a3d8..d81efbe 100644 --- a/vke/src/DescriptorPool.cs +++ b/vke/src/DescriptorPool.cs @@ -87,11 +87,8 @@ namespace CVKL { Utils.CheckResult (vkFreeDescriptorSets (Dev.VkDev, handle, 1, ref descriptorSets[0].handle)); return; } - using (NativeList<VkDescriptorSet> dSets = new NativeList<VkDescriptorSet> ((uint)descriptorSets.Length)) { - foreach (DescriptorSet ds in descriptorSets) - dSets.Add (ds.handle); - Utils.CheckResult (vkFreeDescriptorSets (Dev.VkDev, handle, dSets.Count, dSets.Data)); - } + Utils.CheckResult (vkFreeDescriptorSets (Dev.VkDev, handle, (uint)descriptorSets.Length, descriptorSets.Pin())); + descriptorSets.Unpin (); } public void Reset () { Utils.CheckResult (vkResetDescriptorPool (Dev.VkDev, handle, 0)); diff --git a/vke/src/Device.cs b/vke/src/Device.cs index 1460c81..af9d241 100644 --- a/vke/src/Device.cs +++ b/vke/src/Device.cs @@ -136,11 +136,13 @@ namespace CVKL { public void ResetFence (VkFence fence) { vkResetFences (dev, 1, ref fence); } - public void WaitForFences (NativeList<VkFence> fences, ulong timeOut = UInt64.MaxValue) { - vkWaitForFences (dev, fences.Count, fences.Data, 1, timeOut); + public void WaitForFences (VkFence[] fences, ulong timeOut = UInt64.MaxValue) { + vkWaitForFences (dev, (uint)fences.Length, fences.Pin(), 1, timeOut); + fences.Unpin (); } - public void ResetFences (NativeList<VkFence> fences) { - vkResetFences (dev, fences.Count, fences.Data); + public void ResetFences (params VkFence[] fences) { + vkResetFences (dev, (uint)fences.Length, fences.Pin()); + fences.Unpin (); } public void DestroyShaderModule (VkShaderModule module) { diff --git a/vke/src/ExtensionMethods.cs b/vke/src/ExtensionMethods.cs index 632669b..c731f33 100644 --- a/vke/src/ExtensionMethods.cs +++ b/vke/src/ExtensionMethods.cs @@ -79,7 +79,15 @@ namespace CVKL { handles.Add (obj, hnd); return hnd.AddrOfPinnedObject (); } - public static IntPtr Pin (this string obj) { + public static IntPtr Pin<T> (this T[] obj) { + if (handles.ContainsKey (obj)) + Debug.WriteLine ("Pinning already pinned object: {0}", obj); + + GCHandle hnd = GCHandle.Alloc (obj, GCHandleType.Pinned); + handles.Add (obj, hnd); + return hnd.AddrOfPinnedObject (); + } + public static IntPtr Pin (this string obj) { if (handles.ContainsKey (obj)) { Debug.WriteLine ("Trying to pin already pinned object: {0}", obj); return handles[obj].AddrOfPinnedObject (); diff --git a/vke/src/Instance.cs b/vke/src/Instance.cs index 06fcfe2..589b88b 100644 --- a/vke/src/Instance.cs +++ b/vke/src/Instance.cs @@ -67,18 +67,18 @@ namespace CVKL { get { return inst.Handle; } } - void init () { - NativeList<IntPtr> instanceExtensions = new NativeList<IntPtr> (); - NativeList<IntPtr> enabledLayerNames = new NativeList<IntPtr> (); + void init () { + 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 (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 DEBUG instanceExtensions.Add (Strings.VK_EXT_DEBUG_REPORT_EXTENSION_NAME); @@ -96,31 +96,33 @@ namespace CVKL { pEngineName = Strings.Name, }; - VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo.New(); - instanceCreateInfo.pApplicationInfo = appInfo.Pin(); + VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo.New (); + instanceCreateInfo.pApplicationInfo = appInfo.Pin (); if (instanceExtensions.Count > 0) { - instanceCreateInfo.enabledExtensionCount = instanceExtensions.Count; - instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.Data; + instanceCreateInfo.enabledExtensionCount = (uint)instanceExtensions.Count; + instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.Pin (); } if (enabledLayerNames.Count > 0) { - instanceCreateInfo.enabledLayerCount = enabledLayerNames.Count; - instanceCreateInfo.ppEnabledLayerNames = enabledLayerNames.Data; + instanceCreateInfo.enabledLayerCount = (uint)enabledLayerNames.Count; + instanceCreateInfo.ppEnabledLayerNames = enabledLayerNames.Pin (); } VkResult result = vkCreateInstance (ref instanceCreateInfo, IntPtr.Zero, out inst); - if (result != VkResult.Success) - throw new InvalidOperationException ("Could not create Vulkan instance. Error: " + result); + if (result != VkResult.Success) + throw new InvalidOperationException ("Could not create Vulkan instance. Error: " + result); Vk.LoadInstanceFunctionPointers (inst); appInfo.Unpin (); - instanceExtensions.Dispose (); - enabledLayerNames.Dispose (); - } + if (instanceExtensions.Count > 0) + instanceExtensions.Unpin (); + if (enabledLayerNames.Count > 0) + enabledLayerNames.Unpin (); + } - public void GetDelegate<T> (string name, out T del) { + public void GetDelegate<T> (string name, out T del) { using (FixedUtf8String n = new FixedUtf8String (name)) { del = Marshal.GetDelegateForFunctionPointer<T> (vkGetInstanceProcAddr (Handle, (IntPtr)n)); } diff --git a/vke/src/NativeList.cs b/vke/src/NativeList.cs deleted file mode 100644 index c3ac896..0000000 --- a/vke/src/NativeList.cs +++ /dev/null @@ -1,546 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -#if !VALIDATE -using System.Diagnostics; -#endif -namespace VK -{ - public unsafe class NativeList<T> : IEnumerable<T>, IDisposable where T : struct - { - private byte* _dataPtr; - private uint _elementCapacity; - private uint _count; - - public const int DefaultCapacity = 4; - private const float GrowthFactor = 2f; - private static readonly uint s_elementByteSize = InitializeTypeSize(); - - public NativeList() : this(DefaultCapacity) { } - public NativeList(uint capacity) - { - Allocate(capacity); - } - - public NativeList(uint capacity, uint count) - { - Allocate(capacity); - Count = count; - } - - public NativeList(NativeList<T> existingList) - { - Allocate(existingList._elementCapacity); - long size = existingList._count * s_elementByteSize; - System.Buffer.MemoryCopy (_dataPtr, existingList._dataPtr, size, size); - //Unsafe.CopyBlock(_dataPtr, existingList._dataPtr, existingList._count * s_elementByteSize); - } - - public IntPtr Data - { - get - { - ThrowIfDisposed(); - return new IntPtr(_dataPtr); - } - } - - public uint Count - { - get - { - ThrowIfDisposed(); - return _count; - } - set - { - ThrowIfDisposed(); - if (value > _elementCapacity) - { - uint newLements = value - Count; - CoreResize(value); - Unsafe.InitBlock(_dataPtr + _count * s_elementByteSize, 0, newLements * s_elementByteSize); - } - - _count = value; - } - } - - public ref T this[uint index] - { - get - { - ThrowIfDisposed(); -#if VALIDATE - if (index >= _count) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } -#else - Debug.Assert(index < _count); -#endif - return ref Unsafe.AsRef<T>(_dataPtr + index * s_elementByteSize); - } - } - - public ref T this[int index] - { - get - { - ThrowIfDisposed(); -#if VALIDATE - if (index < 0 || index >= _count) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } -#else - Debug.Assert(index >= 0 && index < _count); -#endif - return ref Unsafe.AsRef<T>(_dataPtr + index * s_elementByteSize); - } - } - - public ReadOnlyNativeListView<T> GetReadOnlyView() - { - ThrowIfDisposed(); - return new ReadOnlyNativeListView<T>(this, 0, _count); - } - - public ReadOnlyNativeListView<T> GetReadOnlyView(uint start, uint count) - { - ThrowIfDisposed(); -#if VALIDATE - if (start + count > _count) - { - throw new ArgumentOutOfRangeException(); - } -#else - Debug.Assert(start + count <= _count); -#endif - return new ReadOnlyNativeListView<T>(this, start, count); - } - - public View<ViewType> GetView<ViewType>() where ViewType : struct - { - ThrowIfDisposed(); - return new View<ViewType>(this); - } - - public bool IsDisposed => _dataPtr == null; - - public void Add(ref T item) - { - ThrowIfDisposed(); - if (_count == _elementCapacity) - { - CoreResize((uint)(_elementCapacity * GrowthFactor)); - } - - Unsafe.Copy(_dataPtr + _count * s_elementByteSize, ref item); - _count += 1; - } - - public void Add(T item) - { - ThrowIfDisposed(); - if (_count == _elementCapacity) - { - CoreResize((uint)(_elementCapacity * GrowthFactor)); - } - - Unsafe.Write(_dataPtr + _count * s_elementByteSize, item); - _count += 1; - } - - public void Add(void* data, uint numElements) - { - ThrowIfDisposed(); - uint needed = _count + numElements; - if (numElements > _elementCapacity) - { - CoreResize((uint)(needed * GrowthFactor)); - } - - Unsafe.CopyBlock(_dataPtr + _count * s_elementByteSize, data, numElements * s_elementByteSize); - _count += numElements; - } - - public bool Remove(ref T item) - { - ThrowIfDisposed(); - bool result = IndexOf(ref item, out uint index); - if (result) - { - CoreRemoveAt(index); - } - - return result; - } - - public bool Remove(T item) => Remove(ref item); - - public void RemoveAt(uint index) - { - ThrowIfDisposed(); -#if VALIDATE - if (index >= _count) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } -#else - Debug.Assert(index < _count); -#endif - CoreRemoveAt(index); - } - - public void Clear() - { - ThrowIfDisposed(); - _count = 0; - } - - public bool IndexOf(ref T item, out uint index) - { - ThrowIfDisposed(); - byte* itemPtr = (byte*)Unsafe.AsPointer(ref item); - for (index = 0; index < _count; index++) - { - byte* ptr = _dataPtr + index * s_elementByteSize; - if (Equals(ptr, itemPtr, s_elementByteSize)) - { - return true; - } - } - - return false; - } - - public bool IndexOf(T item, out uint index) - { - ThrowIfDisposed(); - byte* itemPtr = (byte*)Unsafe.AsPointer(ref item); - for (index = 0; index < _count; index++) - { - byte* ptr = _dataPtr + index * s_elementByteSize; - if (Equals(ptr, itemPtr, s_elementByteSize)) - { - return true; - } - } - - return false; - } - - public IntPtr GetAddress(uint index) - { - ThrowIfDisposed(); -#if VALIDATE - if (index >= _count) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } - -#else - Debug.Assert(index < _count); -#endif - return new IntPtr(_dataPtr + (index * s_elementByteSize)); - } - - public void Resize(uint elementCount) - { - ThrowIfDisposed(); - CoreResize(elementCount); - if (_elementCapacity < _count) - { - _count = _elementCapacity; - } - } - - private static uint InitializeTypeSize() - { -#if VALIDATE - // TODO: DHetermine if the structure type contains references and throw if it does. - // https://github.com/dotnet/corefx/issues/14047 -#endif - return (uint)Unsafe.SizeOf<T>(); - } - - private void CoreResize(uint elementCount) - { - _dataPtr = (byte*)Marshal.ReAllocHGlobal(new IntPtr(_dataPtr), (IntPtr)(elementCount * s_elementByteSize)); - _elementCapacity = elementCount; - } - - private void Allocate(uint elementCount) - { - _dataPtr = (byte*)Marshal.AllocHGlobal((int)(elementCount * s_elementByteSize)); - _elementCapacity = elementCount; - } - - private bool Equals(byte* ptr, byte* itemPtr, uint s_elementByteSize) - { - for (int i = 0; i < s_elementByteSize; i++) - { - if (ptr[i] != itemPtr[i]) - { - return false; - } - } - - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void CoreRemoveAt(uint index) - { - Unsafe.CopyBlock(_dataPtr + index * s_elementByteSize, _dataPtr + (_count - 1) * s_elementByteSize, s_elementByteSize); - _count -= 1; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#if !VALIDATE - [Conditional("DEBUG")] -#endif - private void ThrowIfDisposed() - { -#if VALIDATE - if (_dataPtr == null) - { - throw new ObjectDisposedException(nameof(Data)); - } -#else - Debug.Assert(_dataPtr != null, "NativeList is disposed."); -#endif - } - - public void Dispose() - { - ThrowIfDisposed(); - Marshal.FreeHGlobal(new IntPtr(_dataPtr)); - _dataPtr = null; - } - -#if DEBUG - ~NativeList() - { - if (_dataPtr != null) - { - Debug.WriteLine($"A NativeList<{typeof(T).Name}> was not properly disposed."); - Dispose(); - } - } -#endif - - public Enumerator GetEnumerator() - { - ThrowIfDisposed(); - return new Enumerator(_dataPtr, _count); - } - - IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public struct Enumerator : IEnumerator<T> - { - private byte* _basePtr; - private uint _count; - private uint _currentIndex; - private T _current; - - public Enumerator(byte* basePtr, uint count) - { - _basePtr = basePtr; - _count = count; - _currentIndex = 0; - _current = default(T); - } - - public T Current => _current; - object IEnumerator.Current => Current; - - public bool MoveNext() - { - if (_currentIndex != _count) - { - _current = Unsafe.Read<T>(_basePtr + _currentIndex * s_elementByteSize); - _currentIndex += 1; - return true; - } - - return false; - } - - public void Reset() - { - _current = default(T); - _currentIndex = 0; - } - - public void Dispose() { } - } - - public struct View<ViewType> : IEnumerable<ViewType> where ViewType : struct - { - private static readonly uint s_elementByteSize = (uint)Unsafe.SizeOf<ViewType>(); - private readonly NativeList<T> _parent; - - public View(NativeList<T> parent) - { - _parent = parent; - } - - public uint Count => (_parent.Count * NativeList<T>.s_elementByteSize) / s_elementByteSize; - - public ViewType this[uint index] - { - get - { -#if VALIDATE - if (index >= Count) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } -#else - Debug.Assert(index < Count); -#endif - return Unsafe.Read<ViewType>(_parent._dataPtr + index * s_elementByteSize); - } - } - - public Enumerator GetEnumerator() => new Enumerator(this); - - IEnumerator<ViewType> IEnumerable<ViewType>.GetEnumerator() => GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public struct Enumerator : IEnumerator<ViewType> - { - private View<ViewType> _view; - private uint _currentIndex; - private ViewType _current; - - public Enumerator(View<ViewType> view) - { - _view = view; - _currentIndex = 0; - _current = default(ViewType); - } - - public ViewType Current => _view[_currentIndex]; - object IEnumerator.Current => Current; - - public bool MoveNext() - { - if (_currentIndex != _view.Count) - { - _current = _view[_currentIndex]; - _currentIndex += 1; - return true; - } - - return false; - } - - public void Reset() - { - _currentIndex = 0; - _current = default(ViewType); - } - - public void Dispose() { } - } - } - } - - public struct ReadOnlyNativeListView<T> : IEnumerable<T> where T : struct - { - private readonly NativeList<T> _list; - private readonly uint _start; - public readonly uint Count; - - public ReadOnlyNativeListView(NativeList<T> list, uint start, uint count) - { - _list = list; - _start = start; - Count = count; - } - - public T this[uint index] - { - get - { -#if VALIDATE - if (index >= Count) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } -#else - Debug.Assert(index < Count); -#endif - return _list[index + _start]; - } - } - - public T this[int index] - { - get - { -#if VALIDATE - if (index < 0 || index >= Count) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } -#else - Debug.Assert(index >= 0 && index < Count); -#endif - return _list[(uint)index + _start]; - } - } - - public Enumerator GetEnumerator() => new Enumerator(this); - - IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public struct Enumerator : IEnumerator<T> - { - private ReadOnlyNativeListView<T> _view; - private uint _currentIndex; - private T _current; - - public Enumerator(ReadOnlyNativeListView<T> view) - { - _view = view; - _currentIndex = view._start; - _current = default(T); - } - - public T Current => _view[_currentIndex]; - object IEnumerator.Current => Current; - - public bool MoveNext() - { - if (_currentIndex != _view._start + _view.Count) - { - _current = _view[_currentIndex]; - _currentIndex += 1; - return true; - } - - return false; - } - - public void Reset() - { - _currentIndex = _view._start; - _current = default(T); - } - - public void Dispose() { } - } - } -} diff --git a/vke/src/PhysicalDevice.cs b/vke/src/PhysicalDevice.cs index bf47ee7..265c6fa 100644 --- a/vke/src/PhysicalDevice.cs +++ b/vke/src/PhysicalDevice.cs @@ -55,23 +55,21 @@ namespace CVKL { return ((IEnumerable<PhysicalDevice>)phys).GetEnumerator (); } - unsafe void init () { + void init () { uint gpuCount = 0; CheckResult (vkEnumeratePhysicalDevices (inst, out gpuCount, IntPtr.Zero)); if (gpuCount <= 0) throw new Exception ("No GPU found"); - NativeList<VkPhysicalDevice> gpus = new NativeList<VkPhysicalDevice> (gpuCount, gpuCount); - //fixed (IntPtr* physicalDevices = gpus) { - CheckResult (vkEnumeratePhysicalDevices (inst, out gpuCount, gpus.Data), - "Could not enumerate physical devices."); - //} + + IntPtr gpus = Marshal.AllocHGlobal (Marshal.SizeOf<IntPtr> ()* (int)gpuCount); + CheckResult (vkEnumeratePhysicalDevices (inst, out gpuCount, gpus), "Could not enumerate physical devices."); + phys = new PhysicalDevice[gpuCount]; - Console.WriteLine ("gpu count " + gpuCount); for (int i = 0; i < gpuCount; i++) - phys[i] = new PhysicalDevice (gpus[i].Handle); + phys[i] = new PhysicalDevice (Marshal.ReadIntPtr(gpus + i * Marshal.SizeOf<IntPtr>())); - gpus.Dispose (); + Marshal.FreeHGlobal (gpus); } } public class PhysicalDevice { diff --git a/vke/src/RenderPass.cs b/vke/src/RenderPass.cs index 33d0d42..aa02af3 100644 --- a/vke/src/RenderPass.cs +++ b/vke/src/RenderPass.cs @@ -130,6 +130,9 @@ namespace CVKL { handle = Dev.CreateRenderPass (renderPassInfo); + foreach (SubPass sp in subpasses) + sp.UnpinLists (); + attachments.Unpin (); spDescs.Unpin (); dependencies.Unpin (); @@ -231,8 +234,6 @@ namespace CVKL { protected override void Dispose (bool disposing) { if (state == ActivableState.Activated) { if (disposing) { - foreach (SubPass sp in subpasses) - sp.Dispose (); } else System.Diagnostics.Debug.WriteLine ("VKE Activable RenderPass disposed by finalizer"); diff --git a/vke/src/SubPass.cs b/vke/src/SubPass.cs index e945e89..016641b 100644 --- a/vke/src/SubPass.cs +++ b/vke/src/SubPass.cs @@ -24,11 +24,57 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using VK; namespace CVKL { - public class MarshaledObject<T> : IDisposable where T : struct { + //public class NativeList2<T> : IDisposable where T : struct { + // const int sizeStep = 4; + // int eltSize; + // int capacity; + // int count; + // IntPtr handle; + + // public IntPtr Pointer => handle; + + // public NativeList2 (T[] array) { + // eltSize = Marshal.SizeOf<T> (); + // capacity = count = array.Length; + // GCHandle hnd = GCHandle.Alloc (array, GCHandleType.Pinned); + // handle = GCHandle.ToIntPtr (hnd); + // } + + // public void Add (T elem) { + // if (count == capacity) { + // } + // } + + // void resize (int newSize) { + + // } + + // #region IDisposable Support + // private bool disposedValue; + // protected virtual void Dispose (bool disposing) { + // if (!disposedValue) { + // if (disposing) { + // } + // handle.Free (); + // disposedValue = true; + // } + // } + // public void Dispose () { + // Dispose (true); + // GC.SuppressFinalize(this); + // } + // ~NativeList2 () { Dispose (false); } + // #endregion + //} + + + public class MarshaledObject<T> : IDisposable where T : struct { + GCHandle handle; public IntPtr Pointer { @@ -62,12 +108,12 @@ namespace CVKL { #endregion } - public class SubPass : IDisposable { - NativeList<VkAttachmentReference> colorRefs; - NativeList<VkAttachmentReference> inputRefs; + public class SubPass { + List<VkAttachmentReference> colorRefs = new List<VkAttachmentReference>(); + List<VkAttachmentReference> inputRefs = new List<VkAttachmentReference>(); MarshaledObject<VkAttachmentReference> depthRef; - NativeList<VkAttachmentReference> resolveRefs; - NativeList<uint> preservedRefs; + List<VkAttachmentReference> resolveRefs = new List<VkAttachmentReference>(); + List<uint> preservedRefs = new List<uint>(); public SubPass () { } @@ -82,30 +128,21 @@ namespace CVKL { } public void AddColorReference (params VkAttachmentReference[] refs) { if (colorRefs == null) - colorRefs = new NativeList<VkAttachmentReference> ((uint)refs.Length); + colorRefs = new List<VkAttachmentReference> (); for (int i = 0; i < refs.Length; i++) colorRefs.Add (refs[i]); } public void AddInputReference (params VkAttachmentReference[] refs) { - if (inputRefs == null) - inputRefs = new NativeList<VkAttachmentReference> ((uint)refs.Length); - for (int i = 0; i < refs.Length; i++) - inputRefs.Add (refs[i]); + inputRefs.AddRange (refs); } public void AddPreservedReference (params uint[] refs) { - if (preservedRefs == null) - preservedRefs = new NativeList<uint> ((uint)refs.Length); - for (int i = 0; i < refs.Length; i++) - preservedRefs.Add (refs[i]); + preservedRefs.AddRange (refs); } public void SetDepthReference (uint attachment, VkImageLayout layout = VkImageLayout.DepthStencilAttachmentOptimal) { DepthReference = new VkAttachmentReference { attachment = attachment, layout = layout }; } public void AddResolveReference (params VkAttachmentReference[] refs) { - if (resolveRefs == null) - resolveRefs = new NativeList<VkAttachmentReference> ((uint)refs.Length); - for (int i = 0; i < refs.Length; i++) - resolveRefs.Add (refs[i]); + resolveRefs.AddRange (refs); } public void AddResolveReference (uint attachment, VkImageLayout layout = VkImageLayout.ColorAttachmentOptimal) { AddResolveReference (new VkAttachmentReference { attachment = attachment, layout = layout }); @@ -118,24 +155,28 @@ namespace CVKL { } } - public VkSubpassDescription SubpassDescription { + /// <summary> + /// after having fetched the vkSubpassDescription structure, the lists of attachment are pinned, + /// so it is mandatory to call the UnpinLists methods after. + /// </summary> + public VkSubpassDescription SubpassDescription { get { VkSubpassDescription subpassDescription = new VkSubpassDescription (); subpassDescription.pipelineBindPoint = VkPipelineBindPoint.Graphics; - if (colorRefs?.Count > 0) { - subpassDescription.colorAttachmentCount = colorRefs.Count; - subpassDescription.pColorAttachments = colorRefs.Data; ; + if (colorRefs.Count > 0) { + subpassDescription.colorAttachmentCount = (uint)colorRefs.Count; + subpassDescription.pColorAttachments = colorRefs.Pin(); ; } - if (inputRefs?.Count > 0) { - subpassDescription.inputAttachmentCount = inputRefs.Count; - subpassDescription.pInputAttachments = inputRefs.Data; ; + if (inputRefs.Count > 0) { + subpassDescription.inputAttachmentCount = (uint)inputRefs.Count; + subpassDescription.pInputAttachments = inputRefs.Pin (); ; } - if (preservedRefs?.Count > 0) { - subpassDescription.preserveAttachmentCount = preservedRefs.Count; - subpassDescription.pPreserveAttachments = preservedRefs.Data; ; + if (preservedRefs.Count > 0) { + subpassDescription.preserveAttachmentCount = (uint)preservedRefs.Count; + subpassDescription.pPreserveAttachments = preservedRefs.Pin (); ; } - if (resolveRefs?.Count > 0) - subpassDescription.pResolveAttachments = resolveRefs.Data; + if (resolveRefs.Count > 0) + subpassDescription.pResolveAttachments = resolveRefs.Pin (); if (depthRef != null) subpassDescription.pDepthStencilAttachment = depthRef.Pointer; @@ -144,31 +185,15 @@ namespace CVKL { } } - /*public void GetAttachmentUsage (uint frameBufferAttachmentIndex, ref VkImageUsageFlags usage, ref VkImageAspectFlags aspect) { - for (int i = 0; i < colorRefs.Count; i++) { - if (colorRefs[i].attachment == frameBufferAttachmentIndex) - Utils.QueryLayoutRequirements (colorRefs[i].layout, ref usage, ref aspect); - } - for (int i = 0; i < inputRefs.Count; i++) { - if (colorRefs[i].attachment == frameBufferAttachmentIndex) - Utils.QueryLayoutRequirements (colorRefs[i].layout, ref usage, ref aspect); - } - }*/ - - #region IDisposable Support - protected virtual void Dispose (bool disposing) { - if (disposing) { - colorRefs?.Dispose (); - inputRefs?.Dispose (); - preservedRefs?.Dispose (); - depthRef?.Dispose (); - resolveRefs?.Dispose (); - } - } - public void Dispose () { - Dispose (true); - GC.SuppressFinalize (this); - } - #endregion + public void UnpinLists () { + if (colorRefs.Count > 0) + colorRefs.Unpin (); + if (inputRefs.Count > 0) + inputRefs.Unpin (); + if (preservedRefs.Count > 0) + preservedRefs.Unpin (); + if (resolveRefs.Count > 0) + resolveRefs.Unpin (); + } } } diff --git a/vke/src/ktx.cs b/vke/src/ktx.cs index 3d62340..af4ab49 100644 --- a/vke/src/ktx.cs +++ b/vke/src/ktx.cs @@ -29,6 +29,7 @@ using System.IO; using VK; using CVKL; using System.Runtime.InteropServices; +using System.Collections.Generic; namespace KTX { @@ -108,10 +109,7 @@ namespace KTX { if (imgType != VkImageType.Image3D) pixelDepth = 1; - - - - + img = new Image (staggingQ.Dev, vkFormat, usage, memoryProperty, pixelWidth, pixelHeight, imgType, samples, tiling, requestedMipsLevels, numberOfArrayElements, pixelDepth, createFlags); @@ -131,62 +129,63 @@ namespace KTX { VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.Transfer); - using (NativeList<VkBufferImageCopy> buffCopies = new NativeList<VkBufferImageCopy> ()) { - VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy { - imageExtent = img.CreateInfo.extent, - imageSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, img.CreateInfo.arrayLayers, 0) - }; + List<VkBufferImageCopy> buffCopies = new List<VkBufferImageCopy> (); - ulong bufferOffset = 0; - uint imgWidth = img.CreateInfo.extent.height; - uint imgHeight = img.CreateInfo.extent.width; + VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy { + imageExtent = img.CreateInfo.extent, + imageSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, img.CreateInfo.arrayLayers, 0) + }; - for (int mips = 0; mips < numberOfMipmapLevels; mips++) { - UInt32 imgSize = br.ReadUInt32 (); + ulong bufferOffset = 0; + uint imgWidth = img.CreateInfo.extent.height; + uint imgHeight = img.CreateInfo.extent.width; - bufferCopyRegion.bufferImageHeight = imgWidth; - bufferCopyRegion.bufferRowLength = imgHeight; - bufferCopyRegion.bufferOffset = bufferOffset; + for (int mips = 0; mips < numberOfMipmapLevels; mips++) { + UInt32 imgSize = br.ReadUInt32 (); - if (createFlags.HasFlag (VkImageCreateFlags.CubeCompatible)) { - IntPtr ptrFace = img.MappedData; - bufferCopyRegion.imageSubresource.layerCount = 1; - for (uint face = 0; face < numberOfFaces; face++) { - bufferCopyRegion.imageSubresource.baseArrayLayer = face; - Marshal.Copy (br.ReadBytes ((int)imgSize), 0, stagging.MappedData + (int)bufferOffset, (int)imgSize); - buffCopies.Add (bufferCopyRegion); - uint faceOffset = imgSize + (imgSize % 4); - ptrFace += (int)faceOffset;//cube padding - bufferOffset += faceOffset; - bufferCopyRegion.bufferOffset = bufferOffset; - } - } else { - Marshal.Copy (br.ReadBytes ((int)imgSize), 0, stagging.MappedData, (int)imgSize); + bufferCopyRegion.bufferImageHeight = imgWidth; + bufferCopyRegion.bufferRowLength = imgHeight; + bufferCopyRegion.bufferOffset = bufferOffset; + + if (createFlags.HasFlag (VkImageCreateFlags.CubeCompatible)) { + IntPtr ptrFace = img.MappedData; + bufferCopyRegion.imageSubresource.layerCount = 1; + for (uint face = 0; face < numberOfFaces; face++) { + bufferCopyRegion.imageSubresource.baseArrayLayer = face; + Marshal.Copy (br.ReadBytes ((int)imgSize), 0, stagging.MappedData + (int)bufferOffset, (int)imgSize); buffCopies.Add (bufferCopyRegion); + uint faceOffset = imgSize + (imgSize % 4); + ptrFace += (int)faceOffset;//cube padding + bufferOffset += faceOffset; + bufferCopyRegion.bufferOffset = bufferOffset; } - bufferOffset += imgSize; - imgWidth /= 2; - imgHeight /= 2; + } else { + Marshal.Copy (br.ReadBytes ((int)imgSize), 0, stagging.MappedData, (int)imgSize); + buffCopies.Add (bufferCopyRegion); } - stagging.Unmap (); - Vk.vkCmdCopyBufferToImage (cmd.Handle, stagging.handle, img.handle, VkImageLayout.TransferDstOptimal, - buffCopies.Count, buffCopies.Data); + bufferOffset += imgSize; + imgWidth /= 2; + imgHeight /= 2; + } + stagging.Unmap (); + Vk.vkCmdCopyBufferToImage (cmd.Handle, stagging.handle, img.handle, VkImageLayout.TransferDstOptimal, + (uint)buffCopies.Count, buffCopies.Pin()); + buffCopies.Unpin (); + if (requestedMipsLevels > numberOfMipmapLevels) + img.BuildMipmaps (cmd); + else + img.SetLayout (cmd, VkImageAspectFlags.Color, + VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal, + VkPipelineStageFlags.Transfer, VkPipelineStageFlags.AllGraphics); - if (requestedMipsLevels > numberOfMipmapLevels) - img.BuildMipmaps (cmd); - else - img.SetLayout (cmd, VkImageAspectFlags.Color, - VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal, - VkPipelineStageFlags.Transfer, VkPipelineStageFlags.AllGraphics); + cmd.End (); - cmd.End (); + staggingQ.Submit (cmd); + staggingQ.WaitIdle (); - staggingQ.Submit (cmd); - staggingQ.WaitIdle (); + cmd.Free (); - cmd.Free (); - } } //for (int mips = 0; mips < numberOfMipmapLevels; mips++) { |