Beispiel #1
0
        private void createVulkanInstance()
        {
            InstanceBuilder builder = new InstanceBuilder();

            builder.SetApplicationName("Thingy");
            builder.SetApplicationVersion(Vk.Version.Make(1, 0, 0));
            builder.SetEngineName("None");
            builder.SetEngineVersion(Vk.Version.Make(1, 0, 0));
            builder.SetApiVersion(Vk.Version.Make(1, 0, 0));

            builder.EnableExtensions(VkHelper.GetGLFWRequiredInstanceExtensions());
            builder.EnableExtensions(this.InstanceExtensions);

            if (this.validationLayersEnabled)
            {
                builder.EnableExtensions(this.ValidationExtensions);
                builder.EnableValidationLayers(this.ValidationLayers);
            }

            try {
                this.Instance = builder.Create();
            } catch (Vk.ResultException result) {
                throw new VkException("An error occurred while creating the Vulkan instance.", result);
            }
        }
Beispiel #2
0
        private void createPipelineWrapper()
        {
            if (!this.swapchainCleanedUp)
            {
                this.Pipeline.Destroy(this);
            }

            this.Device.WaitIdle();

            var builder = new GraphicsPipelineBuilder();

            var support = VkHelper.QuerySwapchainSupport(this.PhysicalDevice, this.Window.VulkanSurface);

            builder.SetCapabilities(support.capabilities);
            builder.SetSurfaceFormat(VkHelper.SelectSwapSurfaceFormat(support.formats));
            builder.SetPresentMode(VkHelper.SelectSwapPresentMode(support.presentModes));
            builder.SetExtent(VkHelper.SelectSwapExtent(support.capabilities, this.Window));
            builder.SetGraphicsFamilyQueueIndex(this.vkQueueFamilies.GraphicsFamily.Value);
            builder.SetPresentFamilyQueueIndex(this.vkQueueFamilies.PresentFamily.Value);
            builder.SetDescriptorSetLayout(this.DescriptorSetLayout);
            builder.SetVertexShader(this.VertexShader);
            builder.SetFragmentShader(this.FragmentShader);

            builder.SetRenderPassCallback((Vk.CommandBuffer buffer) => {
                buffer.CmdBindVertexBuffer(0, this.vkVertexBuffer, 0);
                buffer.CmdBindIndexBuffer(this.vkIndexBuffer, 0, Vk.IndexType.Uint16);
                buffer.CmdDrawIndexed((uint)this.indices.Count, 1, 0, 0, 0);
            });

            this.Pipeline = builder.Create(this);

            this.swapchainCleanedUp = false;
        }
Beispiel #3
0
        public void InitVulkan()
        {
            this.createVulkanInstance();

            if (this.validationLayersEnabled)
            {
                this.debugCallbacks.ForEach((DebugCallbackData callbackData) => {
                    callbackData.wrapper = VkHelper.RegisterDebugReportCallback(this.Instance,
                                                                                callbackData.flags, callbackData.callback);
                });
            }

            this.Window.CreateVulkanSurface();

            this.PhysicalDevice = VkHelper.SelectPhysicalDevice(this.Instance, this.physicalDeviceChecks);

            this.createLogicalDevice();

            this.createShaderModules();

            this.GraphicsQueue = this.Device.GetQueue(this.vkQueueFamilies.GraphicsFamily.Value, 0);
            this.TransferQueue = this.GraphicsQueue;
            this.PresentQueue  = this.Device.GetQueue(this.vkQueueFamilies.PresentFamily.Value, 0);

            this.createGraphicsCommandPool();
            this.createTransferCommandPool();

            this.createVertexBuffer();
            this.createIndexBuffer();

            this.createDescriptorSetLayout();
            this.createPipelineWrapper();

            this.createSyncObjects();
        }
Beispiel #4
0
        private void createShaderModules()
        {
            byte[] fragBytecode = VkHelper.LoadShaderCode("project/bin/frag.spv");
            byte[] vertBytecode = VkHelper.LoadShaderCode("project/bin/vert.spv");

            this.FragmentShader = VkHelper.CreateShaderModule(this.Device, fragBytecode);
            this.VertexShader   = VkHelper.CreateShaderModule(this.Device, vertBytecode);
        }
Beispiel #5
0
        public void EnableValidationLayers()
        {
            bool supported = VkHelper.CheckValidationLayerSupport(this.ValidationLayers);

            this.validationLayersEnabled = supported;

            if (!supported)
            {
                Console.Error.WriteLine("Validation Layers not supported.");
                return;
            }

            this.debugCallbacks = new List <DebugCallbackData>();
        }
Beispiel #6
0
        private void createIndexBuffer()
        {
            var size          = Marshal.SizeOf(typeof(short)) * this.indices.Count;
            var transferUsage = Vk.BufferUsageFlags.TransferSrc;
            var indexUsage    = Vk.BufferUsageFlags.IndexBuffer
                                | Vk.BufferUsageFlags.TransferDst;
            var transferMemoryProps = Vk.MemoryPropertyFlags.DeviceLocal;
            var indexMemoryProps    = Vk.MemoryPropertyFlags.HostVisible
                                      | Vk.MemoryPropertyFlags.HostCoherent;
            var sharingMode = this.GetSharingMode();

            BufferWithMemory stagingBuffer;

            try {
                stagingBuffer = VkHelper.CreateBuffer(this, size, transferUsage,
                                                      transferMemoryProps, sharingMode);
            } catch (Vk.ResultException result) {
                throw new VkException("An error occurred while creating the staging buffer.", result);
            }

            IntPtr memory     = this.Device.MapMemory(stagingBuffer.Memory, 0, size);
            var    indexArray = this.indices.ToArray();

            MemoryManagement.ArrayToPtr <short>(indexArray, memory, false);
            this.Device.UnmapMemory(stagingBuffer.Memory);

            try {
                BufferWithMemory indexBuffer = VkHelper.CreateBuffer(this, size, indexUsage,
                                                                     indexMemoryProps, sharingMode);
                this.vkIndexBuffer       = indexBuffer.Buffer;
                this.vkIndexBufferMemory = indexBuffer.Memory;
            } catch (Vk.ResultException result) {
                throw new VkException("An error occurred while creating the index buffer.", result);
            }

            VkHelper.CopyBuffer(stagingBuffer.Buffer, this.vkIndexBuffer, size, this);

            stagingBuffer.Destroy(this.Device);
        }
Beispiel #7
0
        public void TransitionImageLayout(Vk.Image image, Vk.Format format,
                                          Vk.ImageLayout oldLayout, Vk.ImageLayout newLayout)
        {
            var buffer = this.BeginSingleTimeCommands(this.GraphicsCommandPool);

            var subresourceRange = new Vk.ImageSubresourceRange();

            if (newLayout == Vk.ImageLayout.DepthStencilAttachmentOptimal)
            {
                subresourceRange.AspectMask = Vk.ImageAspectFlags.Depth;

                if (VkHelper.HasStencilComponent(format))
                {
                    subresourceRange.AspectMask |= Vk.ImageAspectFlags.Stencil;
                }
            }
            else
            {
                subresourceRange.AspectMask = Vk.ImageAspectFlags.Color;
            }

            subresourceRange.BaseMipLevel   = 0;
            subresourceRange.LevelCount     = 1;
            subresourceRange.BaseArrayLayer = 0;
            subresourceRange.LayerCount     = 1;

            Vk.PipelineStageFlags srcStage;
            Vk.PipelineStageFlags dstStage;

            var barrier = new Vk.ImageMemoryBarrier();

            barrier.OldLayout           = oldLayout;
            barrier.NewLayout           = newLayout;
            barrier.SrcQueueFamilyIndex = VkConstants.VK_QUEUE_FAMILY_IGNORED;
            barrier.DstQueueFamilyIndex = VkConstants.VK_QUEUE_FAMILY_IGNORED;

            if (oldLayout == Vk.ImageLayout.Undefined && newLayout == Vk.ImageLayout.TransferDstOptimal)
            {
                barrier.SrcAccessMask = 0;
                barrier.DstAccessMask = Vk.AccessFlags.TransferWrite;

                srcStage = Vk.PipelineStageFlags.TopOfPipe;
                dstStage = Vk.PipelineStageFlags.Transfer;
            }
            else if (oldLayout == Vk.ImageLayout.TransferDstOptimal && newLayout == Vk.ImageLayout.ShaderReadOnlyOptimal)
            {
                barrier.SrcAccessMask = Vk.AccessFlags.TransferWrite;
                barrier.DstAccessMask = Vk.AccessFlags.ShaderRead;

                srcStage = Vk.PipelineStageFlags.Transfer;
                dstStage = Vk.PipelineStageFlags.FragmentShader;
            }
            else if (oldLayout == Vk.ImageLayout.Undefined && newLayout == Vk.ImageLayout.DepthStencilAttachmentOptimal)
            {
                barrier.SrcAccessMask = 0;
                barrier.DstAccessMask = Vk.AccessFlags.DepthStencilAttachmentRead
                                        | Vk.AccessFlags.DepthStencilAttachmentWrite;

                srcStage = Vk.PipelineStageFlags.TopOfPipe;
                dstStage = Vk.PipelineStageFlags.EarlyFragmentTests;
            }
            else
            {
                throw new Exception("Unsupported layout transition.");
            }

            barrier.Image            = image;
            barrier.SubresourceRange = subresourceRange;

            buffer.CmdPipelineBarrier(srcStage, dstStage, 0, null, null,
                                      new Vk.ImageMemoryBarrier[] { barrier });

            this.EndSingleTimeCommands(this.GraphicsQueue, this.GraphicsCommandPool, buffer);
        }
Beispiel #8
0
 public SwapchainSupportDetails QuerySwapchainSupport(Vk.PhysicalDevice device) =>
 VkHelper.QuerySwapchainSupport(device, this.Window.VulkanSurface);
Beispiel #9
0
 public bool EnsureQueueFamilySupport(Vk.PhysicalDevice device, Vk.QueueFlags family) =>
 VkHelper.CheckPhysicalDeviceQueueFamilySupport(device,
                                                family, this.Window.VulkanSurface, out this.vkQueueFamilies);