public ChunkAllocator(VkDevice device, uint memoryTypeIndex, bool persistentMapped) { _device = device; _memoryTypeIndex = memoryTypeIndex; _persistentMapped = persistentMapped; _totalMemorySize = persistentMapped ? PersistentMappedChunkSize : UnmappedChunkSize; VkMemoryAllocateInfo memoryAI = VkMemoryAllocateInfo.New(); memoryAI.allocationSize = _totalMemorySize; memoryAI.memoryTypeIndex = _memoryTypeIndex; VkResult result = vkAllocateMemory(_device, ref memoryAI, null, out _memory); CheckResult(result); void *mappedPtr = null; if (persistentMapped) { result = vkMapMemory(_device, _memory, 0, _totalMemorySize, 0, &mappedPtr); CheckResult(result); } VkMemoryBlock initialBlock = new VkMemoryBlock(_memory, 0, _totalMemorySize, _memoryTypeIndex, mappedPtr); _freeBlocks.Add(initialBlock); }
protected void allocateMemory() { VkMemoryAllocateInfo memInfo = VkMemoryAllocateInfo.New(); memInfo.allocationSize = memReqs.size; memInfo.memoryTypeIndex = Dev.GetMemoryTypeIndex(memReqs.memoryTypeBits, MemoryFlags); Utils.CheckResult(vkAllocateMemory(Dev.VkDev, ref memInfo, IntPtr.Zero, out vkMemory)); }
public VkMemoryBlock Allocate( VkPhysicalDeviceMemoryProperties memProperties, uint memoryTypeBits, VkMemoryPropertyFlags flags, bool persistentMapped, ulong size, ulong alignment) { lock (_lock) { uint memoryTypeIndex = FindMemoryType(memProperties, memoryTypeBits, flags); ulong minDedicatedAllocationSize = persistentMapped ? MinDedicatedAllocationSizeDynamic : MinDedicatedAllocationSizeNonDynamic; if (size >= minDedicatedAllocationSize) { VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New(); allocateInfo.allocationSize = size; allocateInfo.memoryTypeIndex = memoryTypeIndex; VkResult allocationResult = vkAllocateMemory(_device, ref allocateInfo, null, out VkDeviceMemory memory); if (allocationResult != VkResult.Success) { throw new VeldridException("Unable to allocate sufficient Vulkan memory."); } void *mappedPtr = null; if (persistentMapped) { VkResult mapResult = vkMapMemory(_device, memory, 0, size, 0, &mappedPtr); if (mapResult != VkResult.Success) { throw new VeldridException("Unable to map newly-allocated Vulkan memory."); } } return(new VkMemoryBlock(memory, 0, size, memoryTypeBits, null, true)); } else { ChunkAllocatorSet allocator = GetAllocator(memoryTypeIndex, persistentMapped); bool result = allocator.Allocate(size, alignment, out VkMemoryBlock ret); if (!result) { throw new VeldridException("Unable to allocate sufficient Vulkan memory."); } return(ret); } } }
public ChunkAllocator(VkDevice device, uint memoryTypeIndex) { _device = device; _memoryTypeIndex = memoryTypeIndex; VkMemoryAllocateInfo memoryAI = VkMemoryAllocateInfo.New(); memoryAI.allocationSize = _totalMemorySize; memoryAI.memoryTypeIndex = _memoryTypeIndex; VkResult result = vkAllocateMemory(_device, ref memoryAI, null, out _memory); CheckResult(result); VkMemoryBlock initialBlock = new VkMemoryBlock(_memory, 0, _totalMemorySize, _memoryTypeIndex); _freeBlocks.Add(initialBlock); }
private void Setup() { disposed = false; VkImageCreateInfo image = VkImageCreateInfo.New(); image.imageType = VkImageType.Image2D; image.format = device.DepthFormat; image.extent = new VkExtent3D() { width = swapchain.width, height = swapchain.height, depth = 1 }; image.mipLevels = 1; image.arrayLayers = 1; image.samples = VkSampleCountFlags.Count1; image.tiling = VkImageTiling.Optimal; image.usage = (VkImageUsageFlags.DepthStencilAttachment | VkImageUsageFlags.TransferSrc); image.flags = 0; VkMemoryAllocateInfo mem_alloc = VkMemoryAllocateInfo.New(); mem_alloc.allocationSize = 0; mem_alloc.memoryTypeIndex = 0; VkImageViewCreateInfo depthStencilView = VkImageViewCreateInfo.New(); depthStencilView.viewType = VkImageViewType.Image2D; depthStencilView.format = device.DepthFormat; depthStencilView.flags = 0; depthStencilView.subresourceRange = new VkImageSubresourceRange(); depthStencilView.subresourceRange.aspectMask = (VkImageAspectFlags.Depth | VkImageAspectFlags.Stencil); depthStencilView.subresourceRange.baseMipLevel = 0; depthStencilView.subresourceRange.levelCount = 1; depthStencilView.subresourceRange.baseArrayLayer = 0; depthStencilView.subresourceRange.layerCount = 1; Util.CheckResult(vkCreateImage(device.device, &image, null, out vkImage)); vkGetImageMemoryRequirements(device.device, vkImage, out VkMemoryRequirements memReqs); mem_alloc.allocationSize = memReqs.size; mem_alloc.memoryTypeIndex = device.vulkanDevice.getMemoryType(memReqs.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal); Util.CheckResult(vkAllocateMemory(device.device, &mem_alloc, null, out vkMem)); Util.CheckResult(vkBindImageMemory(device.device, vkImage, vkMem, 0)); depthStencilView.image = vkImage; Util.CheckResult(vkCreateImageView(device.device, ref depthStencilView, null, out vkView)); }
private void CreateDepthImage(VkPhysicalDevice physicalDevice, uint width, uint height) { VkImageCreateInfo createInfo = VkImageCreateInfo.New(); createInfo.imageType = VkImageType.Image2D; createInfo.extent.width = width; createInfo.extent.height = height; createInfo.extent.depth = 1; createInfo.mipLevels = 1; createInfo.arrayLayers = 1; createInfo.format = VkFormat.D32Sfloat; createInfo.tiling = VkImageTiling.Optimal; createInfo.initialLayout = VkImageLayout.Undefined; createInfo.usage = VkImageUsageFlags.DepthStencilAttachment; createInfo.sharingMode = VkSharingMode.Exclusive; createInfo.samples = VkSampleCountFlags.Count1; VkImage depthImage; Assert(vkCreateImage(device, &createInfo, null, &depthImage)); VkMemoryRequirements memoryRequirements; vkGetImageMemoryRequirements(device, depthImage, &memoryRequirements); VkPhysicalDeviceMemoryProperties memoryProperties = new VkPhysicalDeviceMemoryProperties(); vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties); VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New(); allocateInfo.allocationSize = memoryRequirements.size; allocateInfo.memoryTypeIndex = FDataBuffer <byte> .SelectMemoryType(memoryProperties, memoryRequirements.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal); VkDeviceMemory depthImageMemory; Assert(vkAllocateMemory(device, &allocateInfo, null, &depthImageMemory)); vkBindImageMemory(device, depthImage, depthImageMemory, 0); this.depthImage = depthImage; this.depthImageMemory = depthImageMemory; }
protected virtual void SetupDepthStencil() { VkImageCreateInfo image = VkImageCreateInfo.New(); image.imageType = VkImageType._2d; image.format = DepthFormat; image.extent = new VkExtent3D() { width = Width, height = Height, depth = 1 }; image.mipLevels = 1; image.arrayLayers = 1; image.samples = VkSampleCountFlags._1; image.tiling = VkImageTiling.Optimal; image.usage = (VkImageUsageFlags.DepthStencilAttachment | VkImageUsageFlags.TransferSrc); image.flags = 0; VkMemoryAllocateInfo mem_alloc = VkMemoryAllocateInfo.New(); mem_alloc.allocationSize = 0; mem_alloc.memoryTypeIndex = 0; VkImageViewCreateInfo depthStencilView = VkImageViewCreateInfo.New(); depthStencilView.viewType = VkImageViewType._2d; depthStencilView.format = DepthFormat; depthStencilView.flags = 0; depthStencilView.subresourceRange = new VkImageSubresourceRange(); depthStencilView.subresourceRange.aspectMask = (VkImageAspectFlags.Depth | VkImageAspectFlags.Stencil); depthStencilView.subresourceRange.baseMipLevel = 0; depthStencilView.subresourceRange.levelCount = 1; depthStencilView.subresourceRange.baseArrayLayer = 0; depthStencilView.subresourceRange.layerCount = 1; Util.CheckResult(vkCreateImage(Device, &image, null, out DepthStencil.Image)); vkGetImageMemoryRequirements(Device, DepthStencil.Image, out VkMemoryRequirements memReqs); mem_alloc.allocationSize = memReqs.size; mem_alloc.memoryTypeIndex = VulkanDevice.GetMemoryType(memReqs.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal); Util.CheckResult(vkAllocateMemory(Device, &mem_alloc, null, out DepthStencil.Mem)); Util.CheckResult(vkBindImageMemory(Device, DepthStencil.Image, DepthStencil.Mem, 0)); depthStencilView.image = DepthStencil.Image; Util.CheckResult(vkCreateImageView(Device, ref depthStencilView, null, out DepthStencil.View)); }
internal VkResult AllocateDeviceMemory() { VkMemoryAllocateInfo info = VkMemoryAllocateInfo.New(); info.allocationSize = max_size; info.memoryTypeIndex = memoryTypeIndex; VkResult result = vkAllocateMemory(device.device, &info, null, out vkDeviceMemory); if (result != VkResult.Success) { return(result); } if ((memoryPropertyFlags & VkMemoryPropertyFlags.HostVisible) != 0) { Map(); } 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 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()); }
public FDataBuffer(VkDevice device, VkPhysicalDevice physicalDevice, int length, VkBufferUsageFlags usage, VkSharingMode sharingMode) { this.device = device; VkBufferCreateInfo createInfo = VkBufferCreateInfo.New(); size = (ulong)(sizeof(T) * length); createInfo.size = size; createInfo.usage = usage; createInfo.sharingMode = sharingMode; VkBuffer buffer = VkBuffer.Null; Assert(vkCreateBuffer(device, &createInfo, null, &buffer)); this.Buffer = buffer; VkMemoryRequirements memoryRequirements = new VkMemoryRequirements(); vkGetBufferMemoryRequirements(device, this.Buffer, &memoryRequirements); VkPhysicalDeviceMemoryProperties memoryProperties = new VkPhysicalDeviceMemoryProperties(); vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties); VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New(); allocateInfo.allocationSize = memoryRequirements.size; allocateInfo.memoryTypeIndex = SelectMemoryType(memoryProperties, memoryRequirements.memoryTypeBits, VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent); VkDeviceMemory memory = new VkDeviceMemory(); Assert(vkAllocateMemory(device, &allocateInfo, null, &memory)); Memory = memory; Assert(vkBindBufferMemory(device, this.Buffer, memory, 0)); spanLength = length; }
public VkMemoryBlock Allocate( VkPhysicalDeviceMemoryProperties memProperties, uint memoryTypeBits, VkMemoryPropertyFlags flags, bool persistentMapped, ulong size, ulong alignment, bool dedicated, VkImage dedicatedImage, Vulkan.VkBuffer dedicatedBuffer) { // Round up to the nearest multiple of bufferImageGranularity. size = ((size / _bufferImageGranularity) + 1) * _bufferImageGranularity; _totalAllocatedBytes += size; lock (_lock) { if (!TryFindMemoryType(memProperties, memoryTypeBits, flags, out var memoryTypeIndex)) { throw new VeldridException("No suitable memory type."); } ulong minDedicatedAllocationSize = persistentMapped ? MinDedicatedAllocationSizeDynamic : MinDedicatedAllocationSizeNonDynamic; if (dedicated || size >= minDedicatedAllocationSize) { VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New(); allocateInfo.allocationSize = size; allocateInfo.memoryTypeIndex = memoryTypeIndex; VkMemoryDedicatedAllocateInfoKHR dedicatedAI; if (dedicated) { dedicatedAI = VkMemoryDedicatedAllocateInfoKHR.New(); dedicatedAI.buffer = dedicatedBuffer; dedicatedAI.image = dedicatedImage; allocateInfo.pNext = &dedicatedAI; } VkResult allocationResult = vkAllocateMemory(_device, ref allocateInfo, null, out VkDeviceMemory memory); if (allocationResult != VkResult.Success) { throw new VeldridException("Unable to allocate sufficient Vulkan memory."); } void *mappedPtr = null; if (persistentMapped) { VkResult mapResult = vkMapMemory(_device, memory, 0, size, 0, &mappedPtr); if (mapResult != VkResult.Success) { throw new VeldridException("Unable to map newly-allocated Vulkan memory."); } } return(new VkMemoryBlock(memory, 0, size, memoryTypeBits, mappedPtr, true)); } else { ChunkAllocatorSet allocator = GetAllocator(memoryTypeIndex, persistentMapped); bool result = allocator.Allocate(size, alignment, out VkMemoryBlock ret); if (!result) { throw new VeldridException("Unable to allocate sufficient Vulkan memory."); } return(ret); } } }
private static VkImage LoadTexture(VkDevice device, VkPhysicalDevice physicalDevice, int cmdPoolID, VkQueue queue, string[] paths, uint mipLevels) { Bitmap[] bitmaps = new Bitmap[paths.Length]; FDataBuffer <byte>[] tempBuffer = new FDataBuffer <byte> [paths.Length]; uint width = 0, height = 0; for (int j = 0; j < paths.Length; j++) { bitmaps[j] = new Bitmap(System.Drawing.Image.FromFile(paths[j])); var data = bitmaps[j].LockBits(new Rectangle(0, 0, bitmaps[j].Width, bitmaps[j].Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmaps[j].PixelFormat); width = (uint)data.Width; height = (uint)data.Height;//TODO add size check Span <byte> img = new Span <byte>((void *)data.Scan0, data.Stride * data.Height); tempBuffer[j] = new FDataBuffer <byte>(device, physicalDevice, img.Length, VkBufferUsageFlags.TransferSrc, VkSharingMode.Exclusive); Span <byte> buffer = tempBuffer[j].Map(); for (int i = 0; i < img.Length; i += 4) { buffer[i + 2] = img[i]; buffer[i + 1] = img[i + 1]; buffer[i] = img[i + 2]; buffer[i + 3] = img[i + 3]; } buffer = tempBuffer[j].UnMap(); } VkImage texture = VkImage.Null; VkDeviceMemory memory = VkDeviceMemory.Null; VkImageCreateInfo createInfo = VkImageCreateInfo.New(); createInfo.imageType = VkImageType.Image2D; createInfo.extent.width = width; createInfo.extent.height = height; createInfo.extent.depth = 1; createInfo.mipLevels = mipLevels; createInfo.arrayLayers = (uint)paths.Length; createInfo.format = VkFormat.R8g8b8a8Unorm; createInfo.tiling = VkImageTiling.Optimal; createInfo.initialLayout = VkImageLayout.Undefined; createInfo.usage = VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferSrc; createInfo.sharingMode = VkSharingMode.Exclusive; createInfo.samples = VkSampleCountFlags.Count1; Assert(vkCreateImage(device, &createInfo, null, &texture)); VkMemoryRequirements memoryRequirements; vkGetImageMemoryRequirements(device, texture, &memoryRequirements); VkPhysicalDeviceMemoryProperties memoryProperties = new VkPhysicalDeviceMemoryProperties(); vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties); VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New(); allocateInfo.allocationSize = memoryRequirements.size; allocateInfo.memoryTypeIndex = FDataBuffer <byte> .SelectMemoryType(memoryProperties, memoryRequirements.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal); Assert(vkAllocateMemory(device, &allocateInfo, null, &memory)); vkBindImageMemory(device, texture, memory, 0); VkCommandBufferAllocateInfo pAllocateInfo = VkCommandBufferAllocateInfo.New(); pAllocateInfo.commandPool = CommandPoolManager.GetPool(cmdPoolID); pAllocateInfo.level = VkCommandBufferLevel.Primary; pAllocateInfo.commandBufferCount = 1; VkCommandBuffer cmdBuffer = VkCommandBuffer.Null; Assert(vkAllocateCommandBuffers(device, &pAllocateInfo, &cmdBuffer)); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; Assert(vkBeginCommandBuffer(cmdBuffer, &beginInfo)); VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New(); imageMemoryBarrier.srcAccessMask = VkAccessFlags.None; imageMemoryBarrier.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite; imageMemoryBarrier.oldLayout = VkImageLayout.Undefined; imageMemoryBarrier.newLayout = VkImageLayout.TransferDstOptimal; imageMemoryBarrier.srcQueueFamilyIndex = VulkanNative.QueueFamilyIgnored; imageMemoryBarrier.dstQueueFamilyIndex = VulkanNative.QueueFamilyIgnored; imageMemoryBarrier.image = texture; imageMemoryBarrier.subresourceRange = new VkImageSubresourceRange() { baseMipLevel = 0, levelCount = mipLevels, baseArrayLayer = 0, layerCount = (uint)paths.Length, aspectMask = VkImageAspectFlags.Color }; vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion, 0, null, 0, null, 1, &imageMemoryBarrier); for (int j = 0; j < tempBuffer.Length; j++) { VkBufferImageCopy region = new VkBufferImageCopy(); region.bufferOffset = 0; region.bufferRowLength = 0; region.bufferImageHeight = 0; region.imageSubresource.aspectMask = VkImageAspectFlags.Color; region.imageSubresource.mipLevel = 0; region.imageSubresource.baseArrayLayer = (uint)j; region.imageSubresource.layerCount = 1; region.imageOffset = new VkOffset3D(); region.imageExtent = new VkExtent3D() { width = width, height = height, depth = 1 }; vkCmdCopyBufferToImage(cmdBuffer, tempBuffer[j].Buffer, texture, VkImageLayout.TransferDstOptimal, 1, ®ion); } imageMemoryBarrier.oldLayout = VkImageLayout.TransferDstOptimal; imageMemoryBarrier.newLayout = VkImageLayout.ShaderReadOnlyOptimal; vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion, 0, null, 0, null, 1, &imageMemoryBarrier); Assert(vkEndCommandBuffer(cmdBuffer)); VkSubmitInfo submitInfo = VkSubmitInfo.New(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cmdBuffer; Assert(vkQueueSubmit(queue, 1, &submitInfo, VkFence.Null)); Assert(vkQueueWaitIdle(queue)); vkFreeCommandBuffers(device, CommandPoolManager.GetPool(cmdPoolID), 1, &cmdBuffer); return(texture); }