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); } }
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; }
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(); }
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); }
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>(); }
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); }
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); }
public SwapchainSupportDetails QuerySwapchainSupport(Vk.PhysicalDevice device) => VkHelper.QuerySwapchainSupport(device, this.Window.VulkanSurface);
public bool EnsureQueueFamilySupport(Vk.PhysicalDevice device, Vk.QueueFlags family) => VkHelper.CheckPhysicalDeviceQueueFamilySupport(device, family, this.Window.VulkanSurface, out this.vkQueueFamilies);