示例#1
0
        public VkBuffer(VkGraphicsDevice gd, ulong sizeInBytes, bool dynamic, VkBufferUsageFlags usage)
        {
            _gd         = gd;
            SizeInBytes = sizeInBytes;
            usage      |= VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst;

            VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New();

            bufferCI.size  = sizeInBytes;
            bufferCI.usage = usage;
            VkResult result = vkCreateBuffer(gd.Device, ref bufferCI, null, out _deviceBuffer);

            CheckResult(result);

            vkGetBufferMemoryRequirements(gd.Device, _deviceBuffer, out VkMemoryRequirements bufferMemoryRequirements);

            VkMemoryBlock memoryToken = gd.MemoryManager.Allocate(
                gd.PhysicalDeviceMemProperties,
                bufferMemoryRequirements.memoryTypeBits,
                VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                dynamic,
                bufferMemoryRequirements.size,
                bufferMemoryRequirements.alignment);

            _memory = memoryToken;
            result  = vkBindBufferMemory(gd.Device, _deviceBuffer, _memory.DeviceMemory, _memory.Offset);
            CheckResult(result);
        }
示例#2
0
        public TransientBufferManager(VkBufferUsageFlags usage, uint size)
        {
            BufferUsageFlags = usage;
            Size             = size;

            if (usage == VkBufferUsageFlags.UniformBuffer)
            {
                alignment = Device.Properties.limits.minUniformBufferOffsetAlignment;
            }
            else if (usage == VkBufferUsageFlags.StorageBuffer)
            {
                alignment = Device.Properties.limits.minStorageBufferOffsetAlignment;
            }
            else if (usage == VkBufferUsageFlags.UniformTexelBuffer)
            {
                alignment = Device.Properties.limits.minTexelBufferOffsetAlignment;
            }
            else if (usage == VkBufferUsageFlags.IndexBuffer || usage == VkBufferUsageFlags.VertexBuffer || usage == VkBufferUsageFlags.IndirectBuffer)
            {
                // Used to calculate the offset, required when allocating memory (its value should be power of 2)
                alignment = 16;
            }
            else
            {
                throw new Exception("Usage not recognised");
            }
        }
示例#3
0
        public VkDeviceBuffer(
            VkRenderContext rc,
            ulong size,
            VkBufferUsageFlags usage,
            VkMemoryPropertyFlags memoryProperties,
            bool dynamic)
        {
            _rc               = rc;
            usage            |= VkBufferUsageFlags.TransferSrc;
            _usage            = usage;
            _memoryProperties = memoryProperties;
            _isDynamic        = dynamic;

            VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New();

            bufferCI.size  = size;
            bufferCI.usage = _usage;
            VkResult result = vkCreateBuffer(rc.Device, ref bufferCI, null, out _buffer);

            CheckResult(result);

            vkGetBufferMemoryRequirements(rc.Device, _buffer, out _bufferMemoryRequirements);
            _bufferCapacity = _bufferMemoryRequirements.size;
            uint          memoryType  = FindMemoryType(rc.PhysicalDevice, _bufferMemoryRequirements.memoryTypeBits, memoryProperties);
            VkMemoryBlock memoryToken = rc.MemoryManager.Allocate(
                memoryType,
                _bufferMemoryRequirements.size,
                _bufferMemoryRequirements.alignment);

            _memory = memoryToken;
            vkBindBufferMemory(rc.Device, _buffer, _memory.DeviceMemory, _memory.Offset);
        }
示例#4
0
        public Buffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropFlags, ulong stride, ulong count,
                      VkSharingMode sharingMode = VkSharingMode.Exclusive, uint[] queueFamilyIndices = null, IntPtr data = default)
        {
            Stride = stride;
            Count  = count;
            Size   = stride * count;

            // Create the buffer handle
            var bufferCreateInfo = new VkBufferCreateInfo(usageFlags, Size, queueFamilyIndices)
            {
                sharingMode = sharingMode
            };

            if (data != null && (memoryPropertyFlags & VkMemoryPropertyFlags.HostCoherent) == 0)
            {
                bufferCreateInfo.usage |= VkBufferUsageFlags.TransferDst;
            }

            handle = Device.CreateBuffer(ref bufferCreateInfo);

            UsageFlags          = usageFlags;
            memoryPropertyFlags = memoryPropFlags;

            Device.GetBufferMemoryRequirements(handle, out VkMemoryRequirements memReqs);
            Allocate(memReqs);
            Device.BindBufferMemory(handle, memory, 0);

            if (data != IntPtr.Zero)
            {
                SetData(data, 0, Size);
            }

            SetupDescriptor();
        }
        //private void Flush(UInt64 start, UInt64 length) {
        //	VkMappedMemoryRange memoryRange = VkMappedMemoryRange.New();
        //	memoryRange.memory = vkMemory;
        //	memoryRange.size = length;
        //	memoryRange.offset = start;

        //	Util.CheckResult(vkFlushMappedMemoryRanges(device.device, 1, ref memoryRange));
        //}


        private void Allocate()
        {
            if (usageHint == BufferMemoryUsageHint.Static)
            {
                bufferUsageFlags |= VkBufferUsageFlags.TransferDst;
            }

            // Create the buffer handle
            VkBufferCreateInfo bufferCreateInfo = Initializers.bufferCreateInfo(bufferUsageFlags, size);

            bufferCreateInfo.sharingMode = VkSharingMode.Exclusive;
            Util.CheckResult(vkCreateBuffer(device.device, &bufferCreateInfo, null, out vkBuffer));

            // Create the memory backing up the buffer handle
            VkMemoryRequirements memReqs;

            vkGetBufferMemoryRequirements(device.device, vkBuffer, &memReqs);

            var hostVisible = usageHint == BufferMemoryUsageHint.Dynamic;

            memory = device.memoryAllocator.Allocate(memReqs, hostVisible);

            // Attach the memory to the buffer object
            Util.CheckResult(vkBindBufferMemory(device.device, vkBuffer, memory.vkDeviceMemory, memory.offset));
        }
示例#6
0
        public VkBuffer(VkGraphicsDevice gd, uint sizeInBytes, BufferUsage usage)
        {
            _gd         = gd;
            SizeInBytes = sizeInBytes;
            Usage       = usage;

            VkBufferUsageFlags vkUsage = VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst;

            if ((usage & BufferUsage.VertexBuffer) == BufferUsage.VertexBuffer)
            {
                vkUsage |= VkBufferUsageFlags.VertexBuffer;
            }
            if ((usage & BufferUsage.IndexBuffer) == BufferUsage.IndexBuffer)
            {
                vkUsage |= VkBufferUsageFlags.IndexBuffer;
            }
            if ((usage & BufferUsage.UniformBuffer) == BufferUsage.UniformBuffer)
            {
                vkUsage |= VkBufferUsageFlags.UniformBuffer;
            }
            if ((usage & BufferUsage.StructuredBufferReadWrite) == BufferUsage.StructuredBufferReadWrite ||
                (usage & BufferUsage.StructuredBufferReadOnly) == BufferUsage.StructuredBufferReadOnly)
            {
                vkUsage |= VkBufferUsageFlags.StorageBuffer;
            }
            if ((usage & BufferUsage.IndirectBuffer) == BufferUsage.IndirectBuffer)
            {
                vkUsage |= VkBufferUsageFlags.IndirectBuffer;
            }

            VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New();

            bufferCI.size  = sizeInBytes;
            bufferCI.usage = vkUsage;
            VkResult result = vkCreateBuffer(gd.Device, ref bufferCI, null, out _deviceBuffer);

            CheckResult(result);

            vkGetBufferMemoryRequirements(gd.Device, _deviceBuffer, out _bufferMemoryRequirements);

            bool hostVisible = (usage & BufferUsage.Dynamic) == BufferUsage.Dynamic ||
                               (usage & BufferUsage.Staging) == BufferUsage.Staging;

            VkMemoryPropertyFlags memoryPropertyFlags =
                hostVisible
                ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent
                : VkMemoryPropertyFlags.DeviceLocal;

            VkMemoryBlock memoryToken = gd.MemoryManager.Allocate(
                gd.PhysicalDeviceMemProperties,
                _bufferMemoryRequirements.memoryTypeBits,
                memoryPropertyFlags,
                hostVisible,
                _bufferMemoryRequirements.size,
                _bufferMemoryRequirements.alignment);

            _memory = memoryToken;
            result  = vkBindBufferMemory(gd.Device, _deviceBuffer, _memory.DeviceMemory, _memory.Offset);
            CheckResult(result);
        }
 public DeviceBuffer(GraphicsDevice device, UInt64 size, BufferUsageFlags flags, BufferMemoryUsageHint usageHint)
 {
     this.device           = device;
     this.size             = size;
     this.bufferUsageFlags = (VkBufferUsageFlags)flags;
     this.usageHint        = usageHint;
     Allocate();
 }
 internal DeviceBuffer(GraphicsDevice device, UInt64 size, void *data, BufferUsageFlags flags, BufferMemoryUsageHint usageHint)
 {
     this.device           = device;
     this.size             = size;
     this.bufferUsageFlags = (VkBufferUsageFlags)flags;
     this.usageHint        = usageHint;
     Allocate();
     StagingTransfer(0, size, data);
 }
示例#9
0
 public SharedBuffer(VkBufferUsageFlags bufferUsage, uint size)
 {
     buffers[0] = new Buffer(bufferUsage, VkMemoryPropertyFlags.HostVisible, size);
     buffers[0].Map(0, size);
     buffers[1] = new Buffer(bufferUsage, VkMemoryPropertyFlags.HostVisible, size);
     buffers[1].Map(0, size);
     buffers[2] = new Buffer(bufferUsage, VkMemoryPropertyFlags.HostVisible, size);
     buffers[2].Map(0, size);
 }
示例#10
0
        /// <summary>
        /// Create a vulkan buffer and automatically activate it. Automatic activation on startup implies to explicitly dispose the buffer.
        /// </summary>
        /// <param name="device">Logical Device.</param>
        /// <param name="usage">a bitmask specifying allowed usages of the buffer</param>
        /// <param name="_memoryPropertyFlags">Memory property flags.</param>
        /// <param name="size">Desired size in byte of the buffer to be created.</param>
        /// <param name="sharingMode">value specifying the sharing mode of the buffer when it will be accessed by multiple queue familie</param>
        public Buffer(Device device, VkBufferUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags, UInt64 size, VkSharingMode sharingMode = VkSharingMode.Exclusive)
            : base(device, _memoryPropertyFlags)
        {
            createInfo.size        = size;
            createInfo.usage       = usage;
            createInfo.sharingMode = VkSharingMode.Exclusive;

            Activate();
        }
示例#11
0
文件: Buffer.cs 项目: Svengali/vk.net
        public Buffer(Device device, VkBufferUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags, UInt64 size)
            : base(device, _memoryPropertyFlags)
        {
            createInfo.size        = size;
            createInfo.usage       = usage;
            createInfo.sharingMode = VkSharingMode.Exclusive;

            Activate(); //DONT OVERRIDE Activate in derived classes!!!!
        }
示例#12
0
文件: VulkanDevice.cs 项目: gomson/vk
        public VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, ulong size, out VkBuffer buffer, out VkDeviceMemory memory, void *data = null)
        {
            VkBuffer       b;
            VkDeviceMemory dm;
            VkResult       result = createBuffer(usageFlags, memoryPropertyFlags, size, &b, &dm, data);

            buffer = b;
            memory = dm;
            return(result);
        }
示例#13
0
 public SharedBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropFlags, ulong size,
                     VkSharingMode sharingMode = VkSharingMode.Exclusive, uint[] queueFamilyIndices = null)
 {
     buffers[0] = new Buffer(usageFlags, memoryPropFlags, size, 1, sharingMode, queueFamilyIndices);
     buffers[0].Map(0, size);
     buffers[1] = new Buffer(usageFlags, memoryPropFlags, size, 1, sharingMode, queueFamilyIndices);
     buffers[1].Map(0, size);
     buffers[2] = new Buffer(usageFlags, memoryPropFlags, size, 1, sharingMode, queueFamilyIndices);
     buffers[2].Map(0, size);
 }
示例#14
0
文件: Initializers.cs 项目: gomson/vk
        public static VkBufferCreateInfo bufferCreateInfo(
            VkBufferUsageFlags usage,
            ulong size)
        {
            VkBufferCreateInfo bufCreateInfo = VkBufferCreateInfo.New();

            bufCreateInfo.usage = usage;
            bufCreateInfo.size  = size;
            return(bufCreateInfo);
        }
示例#15
0
 /// <summary>
 /// Create and populate a mappable vulkan buffer.
 /// </summary>
 /// <param name="device">Logical Device.</param>
 /// <param name="usage">Buffer Usage.</param>
 /// <param name="data">an array  of T which will be used to populate the buffer.</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, T[] data, bool keepMapped = false, bool coherentMem = true)
     : base(device, usage, (ulong)(Marshal.SizeOf <T> () * data.Length), keepMapped, coherentMem)
 {
     TSize = Marshal.SizeOf <T> ();
     Map();
     Update(data, createInfo.size);
     if (!keepMapped)
     {
         Unmap();
     }
 }
示例#16
0
        void CreateBuffer(long size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, out VkBuffer buffer, out VkDeviceMemory memory)
        {
            var info = new VkBufferCreateInfo();

            info.size        = size;
            info.usage       = usage;
            info.sharingMode = VkSharingMode.Exclusive;

            buffer = new VkBuffer(device, info);

            var allocInfo = new VkMemoryAllocateInfo();

            allocInfo.allocationSize  = buffer.Requirements.size;
            allocInfo.memoryTypeIndex = FindMemoryType(buffer.Requirements.memoryTypeBits, properties);

            memory = new VkDeviceMemory(device, allocInfo);
            buffer.Bind(memory, 0);
        }
示例#17
0
        private void CreateBuffer(ulong size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, out IVkBuffer buffer, out IVkDeviceMemory bufferMemory)
        {
            buffer = device.CreateBuffer(new VkBufferCreateInfo
            {
                Size        = size,
                Usage       = usage,
                SharingMode = VkSharingMode.Exclusive
            }, null).Object;

            var memRequirements = buffer.GetMemoryRequirements();

            bufferMemory = device.AllocateMemory(new VkMemoryAllocateInfo
            {
                AllocationSize  = memRequirements.Size,
                MemoryTypeIndex = FindMemoryType(memRequirements.MemoryTypeBits, properties)
            }, null).Object;

            buffer.BindMemory(bufferMemory, 0).CheckSuccess();
        }
示例#18
0
文件: VulkanDevice.cs 项目: gomson/vk
        /**
         * Create a buffer on the device
         *
         * @param usageFlags Usage flag bitmask for the buffer (i.e. index, vertex, uniform buffer)
         * @param memoryPropertyFlags Memory properties for this buffer (i.e. device local, host visible, coherent)
         * @param size Size of the buffer in byes
         * @param buffer Pointer to the buffer handle acquired by the function
         * @param memory Pointer to the memory handle acquired by the function
         * @param data Pointer to the data that should be copied to the buffer after creation (optional, if not set, no data is copied over)
         *
         * @return VK_SUCCESS if buffer handle and memory have been created and (optionally passed) data has been copied
         */
        public VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, ulong size, VkBuffer *buffer, VkDeviceMemory *memory, void *data = null)
        {
            // Create the buffer handle
            VkBufferCreateInfo bufferCreateInfo = Initializers.bufferCreateInfo(usageFlags, size);

            bufferCreateInfo.sharingMode = VkSharingMode.Exclusive;
            Util.CheckResult(vkCreateBuffer(LogicalDevice, &bufferCreateInfo, null, buffer));

            // Create the memory backing up the buffer handle
            VkMemoryRequirements memReqs;
            VkMemoryAllocateInfo memAlloc = Initializers.memoryAllocateInfo();

            vkGetBufferMemoryRequirements(LogicalDevice, *buffer, &memReqs);
            memAlloc.allocationSize = memReqs.size;
            // Find a memory type index that fits the properties of the buffer
            memAlloc.memoryTypeIndex = GetMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags);
            Util.CheckResult(vkAllocateMemory(LogicalDevice, &memAlloc, null, memory));

            // If a pointer to the buffer data has been passed, map the buffer and copy over the data
            if (data != null)
            {
                void *mapped;
                Util.CheckResult(vkMapMemory(LogicalDevice, *memory, 0, size, 0, &mapped));
                Unsafe.CopyBlock(mapped, data, (uint)size);
                // If host coherency hasn't been requested, do a manual flush to make writes visible
                if ((memoryPropertyFlags & VkMemoryPropertyFlags.HostCoherent) == 0)
                {
                    VkMappedMemoryRange mappedRange = Initializers.mappedMemoryRange();
                    mappedRange.memory = *memory;
                    mappedRange.offset = 0;
                    mappedRange.size   = size;
                    vkFlushMappedMemoryRanges(LogicalDevice, 1, &mappedRange);
                }
                vkUnmapMemory(LogicalDevice, *memory);
            }

            // Attach the memory to the buffer object
            Util.CheckResult(vkBindBufferMemory(LogicalDevice, *buffer, *memory, 0));

            return(VkResult.Success);
        }
示例#19
0
        public unsafe VkBufferCreateInfo(VkBufferUsageFlags usage, ulong size, uint[] queueFamilyIndices = default)
        {
            this.sType       = VkStructureType.BufferCreateInfo;
            this.pNext       = null;
            this.flags       = VkBufferCreateFlags.None;
            this.sharingMode = VkSharingMode.Exclusive;

            if (queueFamilyIndices != null)
            {
                this.queueFamilyIndexCount = (uint)queueFamilyIndices.Length;
                this.pQueueFamilyIndices   = (uint *)Unsafe.AsPointer(ref queueFamilyIndices[0]);
            }
            else
            {
                this.queueFamilyIndexCount = 0;
                this.pQueueFamilyIndices   = null;
            }

            this.usage = usage;
            this.size  = size;
        }
示例#20
0
文件: VulkanDevice.cs 项目: gomson/vk
        /**
         * Create a buffer on the device
         *
         * @param usageFlags Usage flag bitmask for the buffer (i.e. index, vertex, uniform buffer)
         * @param memoryPropertyFlags Memory properties for this buffer (i.e. device local, host visible, coherent)
         * @param buffer Pointer to a vk::Vulkan buffer object
         * @param size Size of the buffer in byes
         * @param data Pointer to the data that should be copied to the buffer after creation (optional, if not set, no data is copied over)
         *
         * @return VK_SUCCESS if buffer handle and memory have been created and (optionally passed) data has been copied
         */
        public VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, vksBuffer buffer, ulong size, void *data = null)
        {
            buffer.device = _logicalDevice;

            // Create the buffer handle
            VkBufferCreateInfo bufferCreateInfo = VkBufferCreateInfo.New();

            bufferCreateInfo.usage = usageFlags;
            bufferCreateInfo.size  = size;
            Util.CheckResult(vkCreateBuffer(_logicalDevice, &bufferCreateInfo, null, out buffer.buffer));

            // Create the memory backing up the buffer handle
            VkMemoryRequirements memReqs;
            VkMemoryAllocateInfo memAlloc = VkMemoryAllocateInfo.New();

            vkGetBufferMemoryRequirements(_logicalDevice, buffer.buffer, &memReqs);
            memAlloc.allocationSize = memReqs.size;
            // Find a memory type index that fits the properties of the buffer
            memAlloc.memoryTypeIndex = GetMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags);
            Util.CheckResult(vkAllocateMemory(_logicalDevice, &memAlloc, null, out buffer.memory));

            buffer.alignment           = memReqs.alignment;
            buffer.size                = memAlloc.allocationSize;
            buffer.usageFlags          = usageFlags;
            buffer.memoryPropertyFlags = memoryPropertyFlags;

            // If a pointer to the buffer data has been passed, map the buffer and copy over the data
            if (data != null)
            {
                Util.CheckResult(buffer.map());
                Unsafe.CopyBlock(buffer.mapped, data, (uint)size);
                buffer.unmap();
            }

            // Initialize a default descriptor that covers the whole buffer size
            buffer.setupDescriptor();

            // Attach the memory to the buffer object
            return(buffer.bind());
        }
示例#21
0
 public GPUBuffer(Device device, VkBufferUsageFlags usage, UInt64 size)
     : base(device, usage, VkMemoryPropertyFlags.DeviceLocal, size)
 {
 }
示例#22
0
 public Buffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, ulong size, VkSharingMode sharingMode = VkSharingMode.Exclusive)
     : this(usageFlags, memoryPropertyFlags, size, 1, sharingMode)
 {
 }
示例#23
0
 public static Buffer Create(VkBufferUsageFlags usageFlags, bool dynamic, ulong stride, ulong count, IntPtr data = default)
 {
     return(new Buffer(usageFlags, dynamic ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent : VkMemoryPropertyFlags.DeviceLocal, stride, count, VkSharingMode.Exclusive, null, data));
 }
示例#24
0
        public VkBuffer(VkGraphicsDevice gd, uint sizeInBytes, BufferUsage usage, string callerMember = null)
        {
            _gd         = gd;
            SizeInBytes = sizeInBytes;
            Usage       = usage;

            VkBufferUsageFlags vkUsage = VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst;

            if ((usage & BufferUsage.VertexBuffer) == BufferUsage.VertexBuffer)
            {
                vkUsage |= VkBufferUsageFlags.VertexBuffer;
            }
            if ((usage & BufferUsage.IndexBuffer) == BufferUsage.IndexBuffer)
            {
                vkUsage |= VkBufferUsageFlags.IndexBuffer;
            }
            if ((usage & BufferUsage.UniformBuffer) == BufferUsage.UniformBuffer)
            {
                vkUsage |= VkBufferUsageFlags.UniformBuffer;
            }
            if ((usage & BufferUsage.StructuredBufferReadWrite) == BufferUsage.StructuredBufferReadWrite ||
                (usage & BufferUsage.StructuredBufferReadOnly) == BufferUsage.StructuredBufferReadOnly)
            {
                vkUsage |= VkBufferUsageFlags.StorageBuffer;
            }
            if ((usage & BufferUsage.IndirectBuffer) == BufferUsage.IndirectBuffer)
            {
                vkUsage |= VkBufferUsageFlags.IndirectBuffer;
            }

            VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New();

            bufferCI.size  = sizeInBytes;
            bufferCI.usage = vkUsage;
            VkResult result = vkCreateBuffer(gd.Device, ref bufferCI, null, out _deviceBuffer);

            CheckResult(result);

            bool prefersDedicatedAllocation;

            if (_gd.GetBufferMemoryRequirements2 != null)
            {
                VkBufferMemoryRequirementsInfo2KHR memReqInfo2 = VkBufferMemoryRequirementsInfo2KHR.New();
                memReqInfo2.buffer = _deviceBuffer;
                VkMemoryRequirements2KHR         memReqs2      = VkMemoryRequirements2KHR.New();
                VkMemoryDedicatedRequirementsKHR dedicatedReqs = VkMemoryDedicatedRequirementsKHR.New();
                memReqs2.pNext = &dedicatedReqs;
                _gd.GetBufferMemoryRequirements2(_gd.Device, &memReqInfo2, &memReqs2);
                _bufferMemoryRequirements  = memReqs2.memoryRequirements;
                prefersDedicatedAllocation = dedicatedReqs.prefersDedicatedAllocation || dedicatedReqs.requiresDedicatedAllocation;
            }
            else
            {
                vkGetBufferMemoryRequirements(gd.Device, _deviceBuffer, out _bufferMemoryRequirements);
                prefersDedicatedAllocation = false;
            }

            bool hostVisible = (usage & BufferUsage.Dynamic) == BufferUsage.Dynamic ||
                               (usage & BufferUsage.Staging) == BufferUsage.Staging;

            VkMemoryPropertyFlags memoryPropertyFlags =
                hostVisible
                ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent
                : VkMemoryPropertyFlags.DeviceLocal;

            VkMemoryBlock memoryToken = gd.MemoryManager.Allocate(
                gd.PhysicalDeviceMemProperties,
                _bufferMemoryRequirements.memoryTypeBits,
                memoryPropertyFlags,
                hostVisible,
                _bufferMemoryRequirements.size,
                _bufferMemoryRequirements.alignment,
                prefersDedicatedAllocation,
                VkImage.Null,
                _deviceBuffer);

            _memory = memoryToken;
            result  = vkBindBufferMemory(gd.Device, _deviceBuffer, _memory.DeviceMemory, _memory.Offset);
            CheckResult(result);

            RefCount = new ResourceRefCount(DisposeCore);
        }
示例#25
0
 public DynamicBuffer(VkBufferUsageFlags bufferUsage, uint size) : base(bufferUsage, size)
 {
     this.Size = size;
 }
示例#26
0
        public unsafe Buffer(
            Device device,
            uint size,
            VkBufferUsageFlags bufferUsageFlags,
            VkMemoryPropertyFlags memoryProperty
            )
        {
            if (size == 0)
            {
                throw new Exception("cannot create buffer with size of zero bytes");
            }

            //make sure buffer supports transfer data to and from buffer
            if ((bufferUsageFlags & VkBufferUsageFlags.TransferSrc) == 0)
            {
                bufferUsageFlags |= VkBufferUsageFlags.TransferSrc;
            }
            if ((bufferUsageFlags & VkBufferUsageFlags.TransferDst) == 0)
            {
                bufferUsageFlags |= VkBufferUsageFlags.TransferDst;
            }

            //store parameter information
            _size           = size;
            _device         = device;
            _bufferUsage    = bufferUsageFlags;
            _memoryProperty = memoryProperty;

            var queueFamilyIndices = new NativeList <uint>();

            foreach (var queueFamily in device.QueueFamilies)
            {
                queueFamilyIndices.Add(queueFamily.Index);
            }

            //buffer create info
            var bufferCreateInfo = new VkBufferCreateInfo
            {
                sType                 = VkStructureType.BufferCreateInfo,
                size                  = size,
                usage                 = bufferUsageFlags,
                sharingMode           = VkSharingMode.Concurrent,
                queueFamilyIndexCount = queueFamilyIndices.Count,
                pQueueFamilyIndices   = (uint *)queueFamilyIndices.Data.ToPointer()
            };

            //setup buffer handler
            VkBuffer buffer;

            if (VulkanNative.vkCreateBuffer(
                    device.Handle,
                    &bufferCreateInfo,
                    null,
                    &buffer
                    ) != VkResult.Success)
            {
                throw new Exception("failed to create vulkan buffer handle");
            }
            _handle = buffer;

            //memory allocation info
            _memoryRequirements = GetMemoryRequirements(device.Handle, buffer);
            var memoryAllocateInfo = new VkMemoryAllocateInfo
            {
                sType           = VkStructureType.MemoryAllocateInfo,
                allocationSize  = _memoryRequirements.size,
                memoryTypeIndex = device.FindMemoryType(
                    _memoryRequirements.memoryTypeBits,
                    _memoryProperty
                    )
            };

            //setup device memory
            VkDeviceMemory deviceMemory;

            if (VulkanNative.vkAllocateMemory(
                    device.Handle,
                    &memoryAllocateInfo,
                    null,
                    &deviceMemory
                    ) != VkResult.Success)
            {
                throw new Exception("failed to allocat device memory");
            }
            _memoryHandle = deviceMemory;

            //bind buffer handle with device memory
            if (VulkanNative.vkBindBufferMemory(
                    device.Handle,
                    buffer,
                    deviceMemory,
                    0
                    ) != VkResult.Success)
            {
                throw new Exception("failed to bind buffer handler to device memory");
            }
        }
示例#27
0
 public static Buffer Create <T>(VkBufferUsageFlags bufferUsages, T[] data, bool dynamic = false) where T : struct
 {
     return(Create(bufferUsages, dynamic, (ulong)Unsafe.SizeOf <T>(), (ulong)data.Length, Utilities.AsPointer(ref data[0])));
 }
示例#28
0
 /// <summary>
 /// Create an empty mappable vulkan buffer for elements of type T whith specified size.
 /// </summary>
 /// <param name="device">Logical Device.</param>
 /// <param name="usage">Buffer Usage.</param>
 /// <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)
     : base(device, usage, (ulong)(Marshal.SizeOf <T> () * arrayElementCount), keepMapped, coherentMem)
 {
     TSize = Marshal.SizeOf <T> ();
 }
示例#29
0
 public static Buffer Create <T>(VkBufferUsageFlags bufferUsages, bool dynamic, ulong count = 1, IntPtr data = default) where T : unmanaged
 {
     return(Create(bufferUsages, dynamic, (ulong)Unsafe.SizeOf <T>(), count, data));
 }
示例#30
0
 public VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, vksBuffer buffer, ulong size, IntPtr data)
 => createBuffer(usageFlags, memoryPropertyFlags, buffer, size, data.ToPointer());