Example #1
0
        public Triangle()
        {
            InitializeComponent();
            InitializeVulkan();
            _Bitmap = new Bitmap(640, 480);

            _Framebuffer = new Framebuffer(_Device, 640, 480);

            VkPipelineLayout dummyLayout = _Device.CreatePipelineLayout(VkPipelineLayoutCreateFlag.NONE, null, null);

            _VertexShader   = _Device.CreateShaderModule(VkShaderModuleCreateFlag.NONE, System.IO.File.ReadAllBytes("./Shaders/vertexShader.spv"));
            _FramgemtShader = _Device.CreateShaderModule(VkShaderModuleCreateFlag.NONE, System.IO.File.ReadAllBytes("./Shaders/fragmentShader.spv"));


            _GraphicsPipeline = new Pipeline(_Framebuffer, dummyLayout, _VertexShader, "main", _FramgemtShader, "main");

            // Finally we will need a fence for our submission in order to wait on it
            _Fence = _Device.CreateFence(VkFenceCreateFlag.NONE);

            // VkBuffer indexBuffer = _Device.CreateBuffer(0, 3 * sizeof(Int32), VkBufferUsageFlag.VK_BUFFER_USAGE_INDEX_BUFFER, VkSharingMode.VK_SHARING_MODE_CONCURRENT, new VkQueueFamilyProperties[] { _Queue.Family });
            // VkBuffer vertexBuffer = _Device.CreateBuffer(0, 3 * sizeof(float), VkBufferUsageFlag.VK_BUFFER_USAGE_VERTEX_BUFFER, VkSharingMode.VK_SHARING_MODE_CONCURRENT, new VkQueueFamilyProperties[] { _Queue.Family });


            // 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.
            VkClearValue.VkClearColorValue.Float color = new VkClearValue.VkClearColorValue.Float();
            color.float32[0] = 0.1f; color.float32[1] = 0.75f; color.float32[2] = 1.0f; color.float32[3] = 1.0f;
            VkCommandPool Pool = _Device.CreateCommandPool(VkCommandPoolCreateFlag.NONE, _Queue.Family);

            _CommandBuffer = Pool.AllocateCommandBuffer(VkCommandBufferLevel.VK_COMMAND_BUFFER_LEVEL_PRIMARY);
            _CommandBuffer.Begin(VkCommandBufferUsageFlag.NONE);
            _CommandBuffer.CmdBeginRenderPass(_Framebuffer.RenderPass,
                                              new VkRect2D(0, 0, (uint)640, (uint)480),
                                              _Framebuffer.GetFramebuffer(),
                                              new VkClearValue[] { color },
                                              VkSubpassContents.VK_SUBPASS_CONTENTS_INLINE);

            _GraphicsPipeline.BindPipeline(_CommandBuffer);
            _CommandBuffer.CmdDraw(3, 1, 0, 0);
            _CommandBuffer.CmdEndRenderPass();
            _CommandBuffer.cmdCopyImageToBuffer(_Framebuffer.FrameBufferColor,
                                                VkImageLayout.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                                _Framebuffer._TransferBuffer,
                                                new VkBufferImageCopy[]
            {
                new VkBufferImageCopy()
                {
                    bufferImageHeight = (uint)_Framebuffer.Height,
                    bufferOffset      = 0,
                    bufferRowLength   = (uint)_Framebuffer.Width,
                    imageExtent       = new VkExtent3D()
                    {
                        depth = 1, width = (uint)_Framebuffer.Width, height = (uint)_Framebuffer.Height
                    },
                    imageSubresource = new VkImageSubresourceLayers()
                    {
                        aspectMask = VkImageAspectFlag.VK_IMAGE_ASPECT_COLOR_BIT, baseArrayLayer = 0, layerCount = 1, mipLevel = 0
                    }
                }
            });
            _CommandBuffer.End();
        }
Example #2
0
        void RecordCommands()
        {
            for (int i = 0; i < swapchainImages.Count; i++)
            {
                VkCommandBuffer commandBuffer = commandBuffers[i];
                commandBuffer.Reset(VkCommandBufferResetFlags.None);
                VkCommandBufferBeginInfo beginInfo = new VkCommandBufferBeginInfo();
                beginInfo.flags = VkCommandBufferUsageFlags.SimultaneousUseBit;
                commandBuffer.Begin(beginInfo);

                //transfer to writable
                commandBuffer.PipelineBarrier(VkPipelineStageFlags.FragmentShaderBit, VkPipelineStageFlags.TransferBit, VkDependencyFlags.None,
                                              null, null,
                                              new List <VkImageMemoryBarrier> {
                    new VkImageMemoryBarrier {
                        image               = textureImage,
                        oldLayout           = VkImageLayout.ShaderReadOnlyOptimal,
                        newLayout           = VkImageLayout.TransferDstOptimal,
                        srcQueueFamilyIndex = -1,    //VK_QUEUE_FAMILY_IGNORED
                        dstQueueFamilyIndex = -1,
                        srcAccessMask       = VkAccessFlags.None,
                        dstAccessMask       = VkAccessFlags.TransferWriteBit,
                        subresourceRange    = new VkImageSubresourceRange {
                            aspectMask     = VkImageAspectFlags.ColorBit,
                            baseArrayLayer = 0,
                            layerCount     = 1,
                            baseMipLevel   = 0,
                            levelCount     = 1
                        }
                    }
                });

                commandBuffer.CopyBufferToImage(stagingBuffer, textureImage, VkImageLayout.TransferDstOptimal,
                                                new VkBufferImageCopy[] {
                    new VkBufferImageCopy {
                        imageExtent = new VkExtent3D {
                            width  = imageWidth,
                            height = imageHeight,
                            depth  = 1
                        },
                        imageSubresource = new VkImageSubresourceLayers {
                            aspectMask     = VkImageAspectFlags.ColorBit,
                            baseArrayLayer = 0,
                            layerCount     = 1,
                            mipLevel       = 0
                        }
                    }
                });

                //transfer to shader readable
                commandBuffer.PipelineBarrier(VkPipelineStageFlags.TransferBit, VkPipelineStageFlags.FragmentShaderBit, VkDependencyFlags.None,
                                              null, null,
                                              new List <VkImageMemoryBarrier> {
                    new VkImageMemoryBarrier {
                        image               = textureImage,
                        oldLayout           = VkImageLayout.TransferDstOptimal,
                        newLayout           = VkImageLayout.ShaderReadOnlyOptimal,
                        srcQueueFamilyIndex = -1,    //VK_QUEUE_FAMILY_IGNORED
                        dstQueueFamilyIndex = -1,
                        srcAccessMask       = VkAccessFlags.TransferWriteBit,
                        dstAccessMask       = VkAccessFlags.ShaderReadBit,
                        subresourceRange    = new VkImageSubresourceRange {
                            aspectMask     = VkImageAspectFlags.ColorBit,
                            baseArrayLayer = 0,
                            layerCount     = 1,
                            baseMipLevel   = 0,
                            levelCount     = 1
                        }
                    }
                });

                VkRenderPassBeginInfo renderPassBeginInfo = new VkRenderPassBeginInfo();
                renderPassBeginInfo.renderPass  = renderPass;
                renderPassBeginInfo.framebuffer = swapchainFramebuffers[i];
                renderPassBeginInfo.renderArea  = new VkRect2D {
                    extent = new VkExtent2D {
                        width  = window.FramebufferWidth,
                        height = window.FramebufferHeight
                    }
                };
                renderPassBeginInfo.clearValues = new List <VkClearValue> {
                    new VkClearValue {
                        color = new VkClearColorValue(0.125f, 0.125f, 0.125f, 0.125f)
                    }
                };

                commandBuffer.BeginRenderPass(renderPassBeginInfo, VkSubpassContents.Inline);

                commandBuffer.BindPipeline(VkPipelineBindPoint.Graphics, pipeline);
                commandBuffer.BindDescriptorSets(VkPipelineBindPoint.Graphics, pipelineLayout, 0, descriptorSet, null);
                commandBuffer.BindVertexBuffers(0, vertexBuffer, 0);
                commandBuffer.BindIndexBuffer(indexBuffer, 0, VkIndexType.UINT32);

                commandBuffer.SetViewports(0, new VkViewport {
                    width    = swapchainExtent.width,
                    height   = swapchainExtent.height,
                    minDepth = 0,
                    maxDepth = 1,
                });
                commandBuffer.SetScissor(0, new VkRect2D {
                    extent = swapchainExtent
                });
                commandBuffer.DrawIndexed(6, 1, 0, 0, 0);

                commandBuffer.EndRenderPass();
                commandBuffer.End();
            }
        }
Example #3
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;
                    }
                }
            }
        }