From: Jean-Philippe Bruyère Date: Mon, 22 Nov 2021 01:40:15 +0000 (+0100) Subject: introduce span for HostBuffer, update triangle sample with it X-Git-Tag: v0.2.4-beta~9 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=24800bfae4c9676e2aef11312eeff1e1cdba9ff4;p=jp%2Fvke.net.git introduce span for HostBuffer, update triangle sample with it --- diff --git a/samples/Triangle/main.cs b/samples/Triangle/main.cs index 82b7374..075f9f3 100644 --- a/samples/Triangle/main.cs +++ b/samples/Triangle/main.cs @@ -35,11 +35,9 @@ namespace Triangle { } } - Matrix4x4 mvp; //the model view projection matrix - HostBuffer ibo; //a host mappable buffer to hold the indices. HostBuffer vbo; //a host mappable buffer to hold vertices. - HostBuffer uboMats; //a host mappable buffer for mvp matrice. + HostBuffer uboMVPmatrix; //a host mappable buffer for mvp matrice. DescriptorPool descriptorPool; DescriptorSet descriptorSet;//descriptor set for the mvp matrice. @@ -62,7 +60,7 @@ namespace Triangle { vbo = new HostBuffer (dev, VkBufferUsageFlags.VertexBuffer, vertices); ibo = new HostBuffer (dev, VkBufferUsageFlags.IndexBuffer, indices); //because mvp matrice may be updated by mouse move, we keep it mapped after creation. - uboMats = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, mvp, true); + uboMVPmatrix = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, 1, true); //a descriptor pool to allocate the mvp matrice descriptor from. descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer)); @@ -101,7 +99,7 @@ namespace Triangle { //Write the content of the descriptor, the mvp matrice. DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descriptorSet, pipeline.Layout.DescriptorSetLayouts[0]); //Descriptor property of the mvp buffer will return a default descriptor with no offset of the full size of the buffer. - uboUpdate.Write (dev, uboMats.Descriptor); + uboUpdate.Write (dev, uboMVPmatrix.Descriptor); //allocate the default VkWindow buffers, one per swapchain image. Their will be only reset when rebuilding and not reallocated. cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount); @@ -109,13 +107,12 @@ namespace Triangle { //view update override, see base method for more informations. public override void UpdateView () { - mvp = + uboMVPmatrix.AsSpan()[0] = Matrix4x4.CreateFromAxisAngle (Vector3.UnitY, rotY) * Matrix4x4.CreateFromAxisAngle (Vector3.UnitX, rotX) * Matrix4x4.CreateTranslation (0, 0, -3f * zoom) * Utils.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (45f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f); - uboMats.Update (mvp, (uint)Marshal.SizeOf ()); base.UpdateView (); } protected override void onMouseMove (double xPos, double yPos) { @@ -181,7 +178,7 @@ namespace Triangle { //resources have to be explicityly disposed. vbo.Dispose (); ibo.Dispose (); - uboMats.Dispose (); + uboMVPmatrix.Dispose (); } } diff --git a/vke/src/base/HostBuffer.cs b/vke/src/base/HostBuffer.cs index f61cb84..19d59e6 100644 --- a/vke/src/base/HostBuffer.cs +++ b/vke/src/base/HostBuffer.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Jean-Philippe Bruyère +// Copyright (c) 2019-2022 Jean-Philippe Bruyère // // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; @@ -13,6 +13,7 @@ namespace vke { /// public class HostBuffer : HostBuffer { int TSize; + int elementCount; /// /// Create an empty mappable vulkan buffer for elements of type T whith specified size. /// @@ -21,8 +22,9 @@ namespace vke { /// Array element count. /// If set to true, buffer will stay mapped after the constructor. /// If set to true vulkan memory with have the coherent flag. - public HostBuffer (Device device, VkBufferUsageFlags usage, uint arrayElementCount, bool keepMapped = false, bool coherentMem = true) + public HostBuffer (Device device, VkBufferUsageFlags usage, int arrayElementCount, bool keepMapped = false, bool coherentMem = true) : base (device, usage, (ulong)(Marshal.SizeOf () * arrayElementCount), keepMapped, coherentMem) { + elementCount = arrayElementCount; TSize = Marshal.SizeOf (); } /// @@ -36,11 +38,21 @@ namespace vke { public HostBuffer (Device device, VkBufferUsageFlags usage, IList data, bool keepMapped = false, bool coherentMem = true) : base (device, usage, (ulong)(Marshal.SizeOf () * data.Count), keepMapped, coherentMem) { TSize = Marshal.SizeOf (); + elementCount = data.Count; Map (); Update (data, createInfo.size); if (!keepMapped) Unmap (); } + public HostBuffer (Device device, VkBufferUsageFlags usage, T data, bool keepMapped = false, bool coherentMem = true) + : base (device, usage, (ulong)(Marshal.SizeOf ()), keepMapped, coherentMem) { + TSize = Marshal.SizeOf (); + elementCount = 1; + Map (); + this.AsSpan()[0] = data; + if (!keepMapped) + Unmap (); + } /// /// Create and populate a mappable vulkan buffer. /// @@ -96,6 +108,42 @@ namespace vke { }; vkFlushMappedMemoryRanges (Dev.VkDev, 1, ref mr); } + /// + /// Retrieve a Span<T> on native memory of the buffer. Automatically Map it if not yet done. + /// + /// Span<T> on native memory valid as long as the buffer is mapped + public Span AsSpan () { + if (!IsMapped) + Map(); + unsafe { + return new Span(mappedData.ToPointer(), elementCount); + } + } + /// + /// Retrieve a Span<T> on native memory of the buffer. Automatically Map it if not yet done. + /// + /// start index in the native memory + /// Span<T> on native memory valid as long as the buffer is mapped + public Span AsSpan (int startIndex) { + if (!IsMapped) + Map(); + unsafe { + return new Span(mappedData.ToPointer(), elementCount).Slice (startIndex); + } + } + /// + /// Retrieve a Span<T> on native memory of the buffer. Automatically Map it if not yet done. + /// + /// start index in the native memory + /// leght of the span to return + /// Span<T> on native memory valid as long as the buffer is mapped + public Span AsSpan (int startIndex, int lenght) { + if (!IsMapped) + Map(); + unsafe { + return new Span(mappedData.ToPointer(), elementCount).Slice (startIndex, lenght); + } + } } /// /// Mappable Buffer with HostVisble and HostCoherent memory flags diff --git a/vke/src/base/Queue.cs b/vke/src/base/Queue.cs index 1818e7f..49b99b2 100644 --- a/vke/src/base/Queue.cs +++ b/vke/src/base/Queue.cs @@ -11,7 +11,7 @@ namespace vke { public class PresentQueue : Queue { public readonly VkSurfaceKHR Surface; - public PresentQueue (Device _dev, VkQueueFlags requestedFlags, VkSurfaceKHR _surface, float _priority = 0.0f) { + public PresentQueue (Device _dev, VkQueueFlags requestedFlags, VkSurfaceKHR _surface, float _priority = 0.0f) { dev = _dev; priority = _priority; Surface = _surface; @@ -19,16 +19,16 @@ namespace vke { qFamIndex = searchQFamily (requestedFlags); dev.queues.Add (this); } - + uint searchQFamily (VkQueueFlags requestedFlags) { //search for dedicated Q for (uint i = 0; i < dev.phy.QueueFamilies.Length; i++) { - if (dev.phy.QueueFamilies[i].queueFlags == requestedFlags && dev.phy.GetPresentIsSupported (i, Surface)) + if (dev.phy.QueueFamilies[i].queueFlags == requestedFlags && dev.phy.GetPresentIsSupported (i, Surface)) return i; } //search Q having flags for (uint i = 0; i < dev.phy.QueueFamilies.Length; i++) { - if ((dev.phy.QueueFamilies[i].queueFlags & requestedFlags) == requestedFlags && dev.phy.GetPresentIsSupported (i, Surface)) + if ((dev.phy.QueueFamilies[i].queueFlags & requestedFlags) == requestedFlags && dev.phy.GetPresentIsSupported (i, Surface)) return i; } diff --git a/vke/src/base/Resource.cs b/vke/src/base/Resource.cs index 0cd0e98..216a3d1 100644 --- a/vke/src/base/Resource.cs +++ b/vke/src/base/Resource.cs @@ -67,8 +67,7 @@ namespace vke { Utils.CheckResult (vkAllocateMemory (Dev.VkDev, ref memInfo, IntPtr.Zero, out vkMemory)); } #endif - - + public bool IsMapped => mappedData != IntPtr.Zero; public void Map (ulong offset = 0) { #if MEMORY_POOLS if (!memoryPool.IsMapped)