/**
         * Get the index of a memory type that has all the requested property bits set
         *
         * @param typeBits Bitmask with bits set for each memory type supported by the resource to request for (from VkMemoryRequirements)
         * @param properties Bitmask of properties for the memory type to request
         * @param (Optional) memTypeFound Pointer to a bool that is set to true if a matching memory type has been found
         *
         * @return Index of the requested memory type
         *
         * @throw Throws an exception if memTypeFound is null and no memory type could be found that supports the requested properties
         */
        public uint getMemoryType(uint typeBits, VkMemoryPropertyFlagBits properties, uint *memTypeFound = null)
        {
            for (uint i = 0; i < MemoryProperties.memoryTypeCount; i++)
            {
                if ((typeBits & 1) == 1)
                {
                    if ((MemoryProperties.GetMemoryType(i).propertyFlags & properties) == properties)
                    {
                        if (memTypeFound != null)
                        {
                            *memTypeFound = True;
                        }
                        return(i);
                    }
                }
                typeBits >>= 1;
            }

            if (memTypeFound != null)
            {
                *memTypeFound = False;
                return(0);
            }
            else
            {
                throw new InvalidOperationException("Could not find a matching memory type");
            }
        }
        public VkResult createBuffer(VkBufferUsageFlagBits usageFlags, VkMemoryPropertyFlagBits 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);
        }
        /**
         * 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 Success if buffer handle and memory have been created and (optionally passed) data has been copied
         */
        public VkResult createBuffer(VkBufferUsageFlagBits usageFlags, VkMemoryPropertyFlagBits memoryPropertyFlags, vksBuffer buffer, ulong size, void *data = null)
        {
            buffer.device = _logicalDevice;

            // Create the buffer handle
            VkBufferCreateInfo bufferCreateInfo = new VkBufferCreateInfo();

            bufferCreateInfo.sType = BufferCreateInfo;
            bufferCreateInfo.usage = usageFlags;
            bufferCreateInfo.size  = size;
            {
                VkBuffer vkBuffer;
                vkCreateBuffer(_logicalDevice, &bufferCreateInfo, null, &vkBuffer);
                buffer.buffer = vkBuffer;
            }

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

            memAlloc.sType = MemoryAllocateInfo;
            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);
            {
                VkDeviceMemory memory;
                vkAllocateMemory(_logicalDevice, &memAlloc, null, &memory);
                buffer.memory = 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)
            {
                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());
        }
示例#4
0
        private int findMemoryType(int typeFilter, VkMemoryPropertyFlagBits properties)
        {
            VkPhysicalDeviceMemoryProperties memProperties;

            Vulkan.vkGetPhysicalDeviceMemoryProperties(physicalDevice, out memProperties);

            for (int i = 0; i < memProperties.memoryTypeCount; i++)
            {
                if ((typeFilter & (1 << i)) != 0 && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
                {
                    return(i);
                }
            }

            throw new Exception("failed to find suitable memory type!");
        }
        /**
         * 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 Success if buffer handle and memory have been created and (optionally passed) data has been copied
         */
        public VkResult createBuffer(VkBufferUsageFlagBits usageFlags, VkMemoryPropertyFlagBits memoryPropertyFlags, ulong size, VkBuffer *buffer, VkDeviceMemory *memory, void *data = null)
        {
            // Create the buffer handle
            VkBufferCreateInfo bufferCreateInfo = new VkBufferCreateInfo();

            bufferCreateInfo.sType       = BufferCreateInfo;
            bufferCreateInfo.usage       = usageFlags;
            bufferCreateInfo.size        = size;
            bufferCreateInfo.sharingMode = VkSharingMode.Exclusive;
            vkCreateBuffer(LogicalDevice, &bufferCreateInfo, null, buffer);

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

            memAlloc.sType = 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);
            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)
            {
                IntPtr mapped;
                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 & VkMemoryPropertyFlagBits.HostCoherent) == 0)
                {
                    VkMappedMemoryRange mappedRange = new VkMappedMemoryRange();
                    mappedRange.memory = *memory;
                    mappedRange.offset = 0;
                    mappedRange.size   = size;
                    vkFlushMappedMemoryRanges(LogicalDevice, 1, &mappedRange);
                }
                vkUnmapMemory(LogicalDevice, *memory);
            }

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

            return(VkResult.Success);
        }
示例#6
0
        //VkMemoryPropertyFlagBits.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
        private uint GetMemoryTypeIndex(VkPhysicalDeviceMemoryProperties memoryProperties, VkMemoryRequirements memoryReq, VkMemoryPropertyFlagBits flags)
        {
            uint          result       = 0;
            bool          heapIndexSet = false;
            VkMemoryType *memoryTypes  = (VkMemoryType *)memoryProperties.memoryTypes;

            for (uint i = 0; i < memoryProperties.memoryTypeCount; i++)
            {
                if (((memoryReq.memoryTypeBits >> (int)i) & 1) == 1 &&
                    (memoryTypes[i].propertyFlags & flags) == flags)
                {
                    result       = i;
                    heapIndexSet = true;
                    break;
                }
            }

            if (!heapIndexSet)
            {
                result = memoryTypes[0].heapIndex;
            }

            return(result);
        }
 public VkResult createBuffer(VkBufferUsageFlagBits usageFlags, VkMemoryPropertyFlagBits memoryPropertyFlags, vksBuffer buffer, ulong size, IntPtr data)
 => createBuffer(usageFlags, memoryPropertyFlags, buffer, size, data.ToPointer());