}
}
- 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<Matrix4x4> uboMVPmatrix; //a host mappable buffer for mvp matrice.
DescriptorPool descriptorPool;
DescriptorSet descriptorSet;//descriptor set for the mvp matrice.
vbo = new HostBuffer<Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
ibo = new HostBuffer<ushort> (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<Matrix4x4> (dev, VkBufferUsageFlags.UniformBuffer, 1, true);
//a descriptor pool to allocate the mvp matrice descriptor from.
descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer));
//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);
//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<Matrix4x4> ());
base.UpdateView ();
}
protected override void onMouseMove (double xPos, double yPos) {
//resources have to be explicityly disposed.
vbo.Dispose ();
ibo.Dispose ();
- uboMats.Dispose ();
+ uboMVPmatrix.Dispose ();
}
}
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+// Copyright (c) 2019-2022 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
/// </summary>
public class HostBuffer<T> : HostBuffer {
int TSize;
+ int elementCount;
/// <summary>
/// Create an empty mappable vulkan buffer for elements of type T whith specified size.
/// </summary>
/// <param name="arrayElementCount">Array element count.</param>
/// <param name="keepMapped">If set to <c>true</c>, buffer will stay mapped after the constructor.</param>
/// <param name="coherentMem">If set to <c>true</c> vulkan memory with have the coherent flag.</param>
- 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<T> () * arrayElementCount), keepMapped, coherentMem) {
+ elementCount = arrayElementCount;
TSize = Marshal.SizeOf<T> ();
}
/// <summary>
public HostBuffer (Device device, VkBufferUsageFlags usage, IList<T> data, bool keepMapped = false, bool coherentMem = true)
: base (device, usage, (ulong)(Marshal.SizeOf<T> () * data.Count), keepMapped, coherentMem) {
TSize = Marshal.SizeOf<T> ();
+ 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<T> ()), keepMapped, coherentMem) {
+ TSize = Marshal.SizeOf<T> ();
+ elementCount = 1;
+ Map ();
+ this.AsSpan()[0] = data;
+ if (!keepMapped)
+ Unmap ();
+ }
/// <summary>
/// Create and populate a mappable vulkan buffer.
/// </summary>
};
vkFlushMappedMemoryRanges (Dev.VkDev, 1, ref mr);
}
+ /// <summary>
+ /// Retrieve a Span<T> on native memory of the buffer. Automatically Map it if not yet done.
+ /// </summary>
+ /// <returns>Span<T> on native memory valid as long as the buffer is mapped</returns>
+ public Span<T> AsSpan () {
+ if (!IsMapped)
+ Map();
+ unsafe {
+ return new Span<T>(mappedData.ToPointer(), elementCount);
+ }
+ }
+ /// <summary>
+ /// Retrieve a Span<T> on native memory of the buffer. Automatically Map it if not yet done.
+ /// </summary>
+ /// <param name="startIndex">start index in the native memory</param>
+ /// <returns>Span<T> on native memory valid as long as the buffer is mapped</returns>
+ public Span<T> AsSpan (int startIndex) {
+ if (!IsMapped)
+ Map();
+ unsafe {
+ return new Span<T>(mappedData.ToPointer(), elementCount).Slice (startIndex);
+ }
+ }
+ /// <summary>
+ /// Retrieve a Span<T> on native memory of the buffer. Automatically Map it if not yet done.
+ /// </summary>
+ /// <param name="startIndex">start index in the native memory</param>
+ /// <param name="lenght">leght of the span to return</param>
+ /// <returns>Span<T> on native memory valid as long as the buffer is mapped</returns>
+ public Span<T> AsSpan (int startIndex, int lenght) {
+ if (!IsMapped)
+ Map();
+ unsafe {
+ return new Span<T>(mappedData.ToPointer(), elementCount).Slice (startIndex, lenght);
+ }
+ }
}
/// <summary>
/// Mappable Buffer with HostVisble and HostCoherent memory flags
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;
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;
}
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)