Exemple #1
0
        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;
                    }
                }
            }
        }