private static VkMemoryType[] GetMemoryTypes(Vulkan.VkPhysicalDeviceMemoryProperties memoryProperties) { VkMemoryType[] types = new VkMemoryType[32]; types[0] = memoryProperties.memoryTypes_0; types[1] = memoryProperties.memoryTypes_1; types[2] = memoryProperties.memoryTypes_2; types[3] = memoryProperties.memoryTypes_3; types[4] = memoryProperties.memoryTypes_4; types[5] = memoryProperties.memoryTypes_5; types[6] = memoryProperties.memoryTypes_6; types[7] = memoryProperties.memoryTypes_7; types[8] = memoryProperties.memoryTypes_8; types[9] = memoryProperties.memoryTypes_9; types[10] = memoryProperties.memoryTypes_10; types[11] = memoryProperties.memoryTypes_11; types[12] = memoryProperties.memoryTypes_12; types[13] = memoryProperties.memoryTypes_13; types[14] = memoryProperties.memoryTypes_14; types[15] = memoryProperties.memoryTypes_15; types[16] = memoryProperties.memoryTypes_16; types[17] = memoryProperties.memoryTypes_17; types[18] = memoryProperties.memoryTypes_18; types[19] = memoryProperties.memoryTypes_19; types[20] = memoryProperties.memoryTypes_20; types[21] = memoryProperties.memoryTypes_21; types[22] = memoryProperties.memoryTypes_22; types[23] = memoryProperties.memoryTypes_23; types[24] = memoryProperties.memoryTypes_24; types[25] = memoryProperties.memoryTypes_25; types[26] = memoryProperties.memoryTypes_26; types[27] = memoryProperties.memoryTypes_27; types[28] = memoryProperties.memoryTypes_28; types[29] = memoryProperties.memoryTypes_29; types[30] = memoryProperties.memoryTypes_30; types[31] = memoryProperties.memoryTypes_31; VkMemoryType[] types2 = new VkMemoryType[memoryProperties.memoryTypeCount]; for (int i = 0; i < types2.Length; i++) { types2[i] = types[i]; } return(types2); }
/// <summary> /// Gets the memory heaps and types for the device. /// </summary> /// <param name="device">The device to get the memory info for.</param> /// <param name="types">The memory types for the device.</param> /// <param name="heaps">The memory heaps for the device.</param> public static void GetMemoryInfo(VkPhysicalDevice device, out VkMemoryType[] types, out VkMemoryHeap[] heaps) { if (!device) { throw new ArgumentNullException(nameof(device), "Cannot pass null device or device handle"); } VkPhysicalDeviceMemoryProperties.New(out var props); device.GetPhysicalDeviceMemoryProperties(&props); VkMemoryType *typePtr = &(props.MemoryTypes_0); VkMemoryHeap *heapPtr = &(props.MemoryHeaps_0); types = new VkMemoryType[props.MemoryTypeCount]; heaps = new VkMemoryHeap[props.MemoryHeapCount]; for (uint i = 0; i < props.MemoryTypeCount; ++i) { types[i] = typePtr[i]; } for (uint i = 0; i < props.MemoryHeapCount; ++i) { heaps[i] = heapPtr[i]; } }
public Framebuffer(VkDevice Device, int Width, int Height) { _Device = Device; _Width = Width; _Height = Height; _FrameBufferColor = _Device.CreateImage(VkImageCreateFlag.NONE, VkFormat.VK_FORMAT_B8G8R8A8_SRGB, Width, Height, 1, 1, VkSampleCountFlag.VK_SAMPLE_COUNT_1, VkImageTiling.VK_IMAGE_TILING_OPTIMAL, VkImageUsageFlag.VK_IMAGE_USAGE_COLOR_ATTACHMENT, VkSharingMode.VK_SHARING_MODE_EXCLUSIVE, null, VkImageLayout.VK_IMAGE_LAYOUT_UNDEFINED); _ImageSize = _FrameBufferColor.MemoryRequirements.size; // We will back this image with Device Accessible Memomy so we can map it an copy // the content from the Host. // To do so we need to find the right memory type first. VkMemoryType deviceMemory = new VkMemoryType(); foreach (VkMemoryType memoryType in _FrameBufferColor.MemoryRequirements.memoryTypes) { // Pick the first memory type that can be mapped into host memory if ((memoryType.propertyFlags & VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_DEVICE_LOCAL) != 0) { deviceMemory = memoryType; break; } } VkDeviceMemory FrameBufferMemory = _Device.AllocateMemory(_FrameBufferColor.MemoryRequirements.size, deviceMemory); _FrameBufferColor.BindMemory(FrameBufferMemory, 0); // Allocate the host visible memory to transfer the framebuffer _TransferBuffer = _Device.CreateBuffer(0, _FrameBufferColor.MemoryRequirements.size, VkBufferUsageFlag.VK_BUFFER_USAGE_TRANSFER_DST, VkSharingMode.VK_SHARING_MODE_EXCLUSIVE, new VkQueueFamilyProperties[] { _Device.Queues[0].Family }); // We will use a host visible buffer so we can map it an copy // the content from the Host. // To do so we need to find the right memory type first. VkMemoryType hostMemory = new VkMemoryType(); foreach (VkMemoryType memoryType in _TransferBuffer.MemoryRequirements.memoryTypes) { // Pick the first memory type that can be mapped into host memory if ((memoryType.propertyFlags & VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_VISIBLE) != 0) { hostMemory = memoryType; break; } } VkDeviceMemory TransferBufferMemory = _Device.AllocateMemory(_ImageSize, hostMemory); _TransferBuffer.BindMemory(TransferBufferMemory, 0); _TransferBufferPtr = TransferBufferMemory.Map(0, _ImageSize, VkMemoryMapFlag.NONE); VkImageView imageView = _FrameBufferColor.CreateImageView(VkImageViewType.VK_IMAGE_VIEW_TYPE_2D, new VkImageSubresourceRange() { aspectMask = VkImageAspectFlag.VK_IMAGE_ASPECT_COLOR_BIT, baseArrayLayer = 0, baseMipLevel = 0, layerCount = 1, levelCount = 1 }); VkAttachmentDescription colorAttachment = new VkAttachmentDescription(); colorAttachment.format = _FrameBufferColor.Format; colorAttachment.samples = VkSampleCountFlag.VK_SAMPLE_COUNT_1; colorAttachment.loadOp = VkAttachmentLoadOp.VK_ATTACHMENT_LOAD_OP_CLEAR; colorAttachment.storeOp = VkAttachmentStoreOp.VK_ATTACHMENT_STORE_OP_STORE; colorAttachment.stencilLoadOp = VkAttachmentLoadOp.VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorAttachment.stencilStoreOp = VkAttachmentStoreOp.VK_ATTACHMENT_STORE_OP_DONT_CARE; colorAttachment.initialLayout = VkImageLayout.VK_IMAGE_LAYOUT_UNDEFINED; colorAttachment.finalLayout = VkImageLayout.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; VkAttachmentReference colorAttachmentReference = new VkAttachmentReference(); colorAttachmentReference.attachment = 0; colorAttachmentReference.layout = VkImageLayout.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; VkSubpassDescription subpass = new VkSubpassDescription(); subpass.pipelineBindPoint = VkPipelineBindPoint.VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachments = new VkAttachmentReference[] { colorAttachmentReference }; subpass.depthStencilAttachment = null; subpass.inputAttachments = null; subpass.preserveAttachments = null; subpass.resolveAttachments = null; VkSubpassDependency dependency = new VkSubpassDependency(); dependency.srcSubpass = VkSubpassDependency.VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VkPipelineStageFlag.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT; dependency.srcAccessMask = 0; dependency.dstStageMask = VkPipelineStageFlag.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT; dependency.dstAccessMask = VkAccessFlag.VK_ACCESS_COLOR_ATTACHMENT_READ | VkAccessFlag.VK_ACCESS_COLOR_ATTACHMENT_WRITE; _RenderPass = _Device.CreateRenderPass(new VkAttachmentDescription[] { colorAttachment }, new VkSubpassDescription[] { subpass }, new VkSubpassDependency[] { dependency }); _Framebuffer = _Device.CreateFramebuffer(_RenderPass, new VkImageView[] { imageView }, (uint)Width, (uint)Height, 1); }
public ClearImage() { InitializeComponent(); _Bitmap = new Bitmap(640, 480); // Create the VUlkan instance that we will use for this app _Instance = new VkInstance("ClearImage - Sample", 1, "Ratchet", 1); // Now lets walk all physical device and find the first one that supports graphics queue foreach (VkPhysicalDevice physicalDevice in _Instance.vkEnumeratePhysicalDevices()) { foreach (VkQueueFamilyProperties queueFamilly in physicalDevice.QueueFamilies) { if ((queueFamilly.queueFlags & VkQueueFlags.VK_QUEUE_GRAPHICS) != 0) { // We have a physical device that supports graphics queue, we can now create a Device on it // with one queue and use it as our main device for this sample _Device = physicalDevice.CreateDevice(new VkDeviceQueueCreateInfo[] { new VkDeviceQueueCreateInfo() { queueCount = 1, queueFamily = queueFamilly, queuePriorities = new float[] { 1.0f } } }); // Ok now lets grab the graphics queue back. Technically there should only be one // But just to be clean we do an iteration and look for the queue that matches our // need foreach (VkQueue queue in _Device.Queues) { if (queue.Family.queueFlags == queueFamilly.queueFlags) { _Queue = queue; break; } } // Now it is time to create the image that we will fill wih the solid color _Image = _Device.CreateImage( VkImageCreateFlag.NONE, VkFormat.VK_FORMAT_B8G8R8A8_SRGB, _Bitmap.Width, _Bitmap.Height, 1, 1, VkSampleCountFlag.VK_SAMPLE_COUNT_1, VkImageTiling.VK_IMAGE_TILING_LINEAR, VkImageUsageFlag.VK_IMAGE_USAGE_TRANSFER_SRC | VkImageUsageFlag.VK_IMAGE_USAGE_TRANSFER_DST, VkSharingMode.VK_SHARING_MODE_EXCLUSIVE, null, VkImageLayout.VK_IMAGE_LAYOUT_GENERAL); // We will back this image with Host Accessible Memomy so we can map it an copy // the content from the Host. // To do so we need to find the right memory type first. VkMemoryType HostMemory = new VkMemoryType(); foreach (VkMemoryType memoryType in _Image.MemoryRequirements.memoryTypes) { // Pick the first memory type that can be mapped into host memory if ((memoryType.propertyFlags & VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_VISIBLE) != 0) { HostMemory = memoryType; break; } } // Allocate the backing memory for this image VkDeviceMemory Memory = _Device.AllocateMemory(_Image.MemoryRequirements.size, HostMemory); _Image.BindMemory(Memory, 0); // Create the CPU mapping _ImagePtr = Memory.Map(0, _Image.MemoryRequirements.size, VkMemoryMapFlag.NONE); // Now we need to create a command buffer and we will fill it with a single command: // Fill the image with the color (0.1f, 0.75f, 1.0f, 1.0f) which is a Sky blue. VkCommandPool Pool = _Device.CreateCommandPool(VkCommandPoolCreateFlag.NONE, _Queue.Family); _CommandBuffer = Pool.AllocateCommandBuffer(VkCommandBufferLevel.VK_COMMAND_BUFFER_LEVEL_PRIMARY); _CommandBuffer.Begin(VkCommandBufferUsageFlag.NONE); _CommandBuffer.CmdClearColorImage( _Image, VkImageLayout.VK_IMAGE_LAYOUT_GENERAL, 0.1f, 0.75f, 1.0f, 1.0f, new VkImageSubresourceRange[] { new VkImageSubresourceRange() { aspectMask = VkImageAspectFlag.VK_IMAGE_ASPECT_COLOR_BIT, baseArrayLayer = 0, baseMipLevel = 0, layerCount = 1, levelCount = 1 } }); _CommandBuffer.End(); // Finally we will need a fence for our submission in order to wait on it _Fence = _Device.CreateFence(VkFenceCreateFlag.NONE); break; } } } }