示例#1
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");
            }
        }