Пример #1
0
        private unsafe List <VkPresentModeKHR> GetSupportedPresentModes(
            Device device,
            NativeWindow window
            )
        {
            uint presentModeCount;

            if (VulkanNative.vkGetPhysicalDeviceSurfacePresentModesKHR(
                    device.PhysicalDevice,
                    window.Surface,
                    &presentModeCount,
                    null
                    ) != VkResult.Success)
            {
                throw new Exception("failed to get device supported present modes");
            }
            var supporedPresentModes = new NativeList <VkPresentModeKHR>(presentModeCount);

            supporedPresentModes.Count = presentModeCount;
            if (VulkanNative.vkGetPhysicalDeviceSurfacePresentModesKHR(
                    device.PhysicalDevice,
                    window.Surface,
                    &presentModeCount,
                    (VkPresentModeKHR *)supporedPresentModes.Data.ToPointer()
                    ) != VkResult.Success)
            {
                throw new Exception("failed to get device supported present modes");
            }
            return(supporedPresentModes.ToList());
        }
Пример #2
0
        public unsafe QueueFamilyIndices(VkPhysicalDevice device, VkSurfaceKHR surface)
        {
            int graphicsIndex = -1;
            int presentIndex  = -1;

            uint queueFamilyCount = 0;

            VulkanNative.vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, null);
            VkQueueFamilyProperties *queueFamilies = stackalloc VkQueueFamilyProperties[(int)queueFamilyCount];

            VulkanNative.vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies);

            for (int i = 0; i < queueFamilyCount; i++)
            {
                var q = queueFamilies[i];

                if (q.queueCount > 0 && (q.queueFlags & VkQueueFlagBits.VK_QUEUE_GRAPHICS_BIT) != 0)
                {
                    graphicsIndex = i;
                }

                VkBool32 presentSupported = false;
                VkResult result           = VulkanNative.vkGetPhysicalDeviceSurfaceSupportKHR(device, (uint)i, surface, &presentSupported);
                Helpers.CheckErrors(result);
                if (presentIndex < 0 && q.queueCount > 0 && presentSupported)
                {
                    presentIndex = i;
                }
            }

            GraphicsFamily = graphicsIndex;
            PresentFamily  = presentIndex;
        }
Пример #3
0
        private unsafe QueueFamily GetQueueFamilyWithPresentationSupport(
            Device device,
            NativeWindow window
            )
        {
            var queueFamiliesSupportingPresentation = new List <bool>();

            foreach (var queueFamily in device.QueueFamilies)
            {
                var isSupported = VkBool32.False;
                if (VulkanNative.vkGetPhysicalDeviceSurfaceSupportKHR(
                        _device.PhysicalDevice,
                        0,
                        window.Surface,
                        &isSupported
                        ) != VkResult.Success)
                {
                    throw new Exception("failed to check if device supports presentation");
                }
                queueFamiliesSupportingPresentation.Add(isSupported);
            }

            var familySupportingPresentation = queueFamiliesSupportingPresentation.FindIndex(
                0, queueFamiliesSupportingPresentation.Count,
                q => q
                );

            if (familySupportingPresentation == -1)
            {
                throw new NotSupportedException("device does not support presentation");
            }
            return(device.QueueFamilies[familySupportingPresentation]);
        }
Пример #4
0
        private unsafe List <VkSurfaceFormatKHR> GetSupportedSurfaceFormats(
            Device device,
            NativeWindow window
            )
        {
            uint surfaceSupportedFormatsCount;

            if (VulkanNative.vkGetPhysicalDeviceSurfaceFormatsKHR(
                    device.PhysicalDevice,
                    window.Surface,
                    &surfaceSupportedFormatsCount,
                    null
                    ) != VkResult.Success)
            {
                throw new Exception("failed to get device support formats");
            }
            var surfaceSupportFormats = new NativeList <VkSurfaceFormatKHR>(surfaceSupportedFormatsCount);

            surfaceSupportFormats.Count = surfaceSupportedFormatsCount;
            if (VulkanNative.vkGetPhysicalDeviceSurfaceFormatsKHR(
                    device.PhysicalDevice,
                    window.Surface,
                    &surfaceSupportedFormatsCount,
                    (VkSurfaceFormatKHR *)surfaceSupportFormats.Data.ToPointer()
                    ) != VkResult.Success)
            {
                throw new Exception("failed to get device support formats");
            }

            return(surfaceSupportFormats.ToList());
        }
Пример #5
0
        public unsafe void BindDescriptorSets(
            Pipeline pipeline,
            List <DescriptorSet> descriptorSets,
            VkPipelineBindPoint bindPoint = VkPipelineBindPoint.Graphics
            )
        {
            var sets = new NativeList <VkDescriptorSet>();

            if (descriptorSets != null)
            {
                foreach (var set in descriptorSets)
                {
                    sets.Add(set.Handle);
                }
            }

            if (sets.Count > 0)
            {
                VulkanNative.vkCmdBindDescriptorSets(
                    _handle,
                    bindPoint,
                    pipeline.Layout,
                    0,
                    sets.Count,
                    (VkDescriptorSet *)sets.Data.ToPointer(),
                    0,
                    null
                    );
            }
        }
Пример #6
0
        public unsafe void Begin(
            VkCommandBufferUsageFlags commandBufferUsageFlag,
            RenderPass renderPass,
            Framebuffer framebuffer,
            uint subpass = 0
            )
        {
            if (_level != VkCommandBufferLevel.Secondary)
            {
                throw new Exception("you can only use this method for secondary command buffers");
            }

            var inheritanceInfo = new VkCommandBufferInheritanceInfo
            {
                sType       = VkStructureType.CommandBufferInheritanceInfo,
                renderPass  = renderPass.Handle,
                framebuffer = framebuffer.Handle
            };

            var beginInfo = new VkCommandBufferBeginInfo
            {
                sType            = VkStructureType.CommandBufferBeginInfo,
                flags            = commandBufferUsageFlag,
                pInheritanceInfo = &inheritanceInfo
            };

            if (VulkanNative.vkBeginCommandBuffer(
                    _handle,
                    &beginInfo
                    ) != VkResult.Success)
            {
                throw new Exception("failed to begin command buffer");
            }
        }
Пример #7
0
        public unsafe void CopyBuffer(
            Buffer source,
            Buffer destination
            )
        {
            if (source.Size > destination.Size)
            {
                throw new InvalidOperationException("source size cannot be greater than destination");
            }

            var region = new VkBufferCopy
            {
                dstOffset = 0,
                srcOffset = 0,
                size      = source.Size
            };

            VulkanNative.vkCmdCopyBuffer(
                _handle,
                source.Handle,
                destination.Handle,
                1,
                &region
                );
        }
Пример #8
0
        public unsafe CommandBuffer(
            CommandPool commandPool,
            VkCommandBufferLevel level = VkCommandBufferLevel.Primary,
            bool isFenceSignaled       = false
            )
        {
            _commandPool = commandPool;
            _level       = level;
            var allocateInfo = new VkCommandBufferAllocateInfo
            {
                sType              = VkStructureType.CommandBufferAllocateInfo,
                commandPool        = commandPool.Handle,
                level              = level,
                commandBufferCount = 1
            };

            VkCommandBuffer commandBuffer;

            if (VulkanNative.vkAllocateCommandBuffers(
                    commandPool.Device.Handle,
                    &allocateInfo,
                    &commandBuffer
                    ) != VkResult.Success)
            {
                throw new Exception("failed to allocate command buffers");
            }
            _handle = commandBuffer;
            _fence  = new Fence(commandPool.Device, isFenceSignaled);
        }
Пример #9
0
        public unsafe void Init(ShaderType type, byte[] compiledShaderCode)
        {
            _type = type;
            fixed(byte *byteCodePtr = compiledShaderCode)
            {
                var shaderInfo = new VkShaderModuleCreateInfo
                {
                    sType    = VkStructureType.ShaderModuleCreateInfo,
                    codeSize = new UIntPtr((uint)compiledShaderCode.Length),
                    pCode    = (uint *)byteCodePtr
                };

                VkShaderModule shaderModule;

                if (VulkanNative.vkCreateShaderModule(
                        _device.Handle,
                        &shaderInfo,
                        null,
                        &shaderModule
                        ) != VkResult.Success)
                {
                    throw new Exception("failed to create shader module");
                }
                _handle = shaderModule;
            }
        }
Пример #10
0
        public unsafe Fence(Device device, bool isSignaled = false)
        {
            _device = device;
            var createInfo = new VkFenceCreateInfo
            {
                sType = VkStructureType.FenceCreateInfo,
                flags = (
                    isSignaled ?
                    VkFenceCreateFlags.Signaled :
                    VkFenceCreateFlags.None
                    )
            };

            VkFence fence;

            if (VulkanNative.vkCreateFence(
                    device.Handle,
                    &createInfo,
                    null,
                    &fence
                    ) != VkResult.Success)
            {
                throw new Exception("failed to create fence");
            }
            _handle = fence;
        }
Пример #11
0
        private void CleanUp()
        {
            VulkanNative.vkDestroySemaphore(this.device, this.renderFinishedSemaphore, null);
            VulkanNative.vkDestroySemaphore(this.device, this.imageAvailableSemaphore, null);

            VulkanNative.vkDestroyCommandPool(this.device, this.commandPool, null);

            VulkanNative.vkDestroyAccelerationStructureKHR(this.device, this.bottomLevelAS, null);

            VulkanNative.vkDestroyAccelerationStructureKHR(this.device, this.topLevelAS, null);

            VulkanNative.vkDestroyDescriptorSetLayout(this.device, this.descriptorSetLayout, null);

            VulkanNative.vkDestroyDescriptorPool(this.device, this.descriptorPool, null);

            VulkanNative.vkDestroyPipeline(this.device, this.pipeline, null);

            VulkanNative.vkDestroyPipelineLayout(this.device, this.pipelineLayout, null);

            VulkanNative.vkDestroySwapchainKHR(this.device, this.swapChain, null);

            VulkanNative.vkDestroyDevice(this.device, null);

            this.DestroyDebugMessenger();

            VulkanNative.vkDestroySurfaceKHR(this.instance, this.surface, null);

            VulkanNative.vkDestroyInstance(this.instance, null);

            this.window.Dispose();
            this.window.Close();
        }
Пример #12
0
        private unsafe VkResult CreateDebugReportCallback(
            VkDebugReportFlagsEXT flags
            )
        {
            _debugCallbackFunction = DebugCallback;
            var debugFunctionPtr  = Marshal.GetFunctionPointerForDelegate(_debugCallbackFunction);
            var debugCallbackInfo = new VkDebugReportCallbackCreateInfoEXT
            {
                sType       = VkStructureType.DebugReportCallbackCreateInfoEXT,
                flags       = flags,
                pfnCallback = debugFunctionPtr
            };

            var createFunctionPtr = VulkanNative.vkGetInstanceProcAddr(
                _handle,
                new FixedUtf8String("vkCreateDebugReportCallbackEXT")
                );

            if (createFunctionPtr == IntPtr.Zero)
            {
                return(VkResult.ErrorValidationFailedEXT);
            }

            var createDelegate = Marshal.GetDelegateForFunctionPointer <vkCreateDebugReportCallbackEXT_d>(
                createFunctionPtr
                );

            return(createDelegate(
                       _handle,
                       &debugCallbackInfo,
                       IntPtr.Zero,
                       out _debugCallbackHandle
                       ));
        }
Пример #13
0
        public unsafe void SetData(IntPtr ptr, int size)
        {
            if (size == 0)
            {
                Console.WriteLine("[WARNING]: cannot set buffer data with zero bytes");
                return;
            }
            if (size > _size)
            {
                Console.WriteLine("[WARNING]: new data size is bigger than buffer size");
                return;
            }

            var mappedMemory = IntPtr.Zero;

            if (VulkanNative.vkMapMemory(
                    _device.Handle,
                    _memoryHandle,
                    0,
                    _size,
                    0,
                    (void **)&mappedMemory
                    ) != VkResult.Success)
            {
                throw new Exception("failed to map device memory");
            }

            System.Buffer.MemoryCopy(
                IntPtr.Add(ptr, 0).ToPointer(),
                IntPtr.Add(mappedMemory, 0).ToPointer(),
                size, size
                );

            VulkanNative.vkUnmapMemory(_device.Handle, _memoryHandle);
        }
Пример #14
0
        private void CreateFrameBuffers()
        {
            vkSwapChainFramebuffers = new VkFramebuffer[vkSwapChainImageViews.Length];

            for (int i = 0; i < vkSwapChainImageViews.Length; i++)
            {
                var attachments = stackalloc VkImageView[] { vkSwapChainImageViews[i] };

                var frameBufferInfo = new VkFramebufferCreateInfo()
                {
                    sType           = VkStructureType.VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
                    renderPass      = vkRenderPass,
                    attachmentCount = 1,
                    pAttachments    = attachments,
                    width           = vkSwapChainExtent.width,
                    height          = vkSwapChainExtent.height,
                    layers          = 1,
                };

                VkFramebuffer newFrameBuffer;
                var           result = VulkanNative.vkCreateFramebuffer(vkDevice, &frameBufferInfo, null, &newFrameBuffer);
                vkSwapChainFramebuffers[i] = newFrameBuffer;
                Helpers.CheckErrors(result);
            }
        }
Пример #15
0
        public unsafe Framebuffer(
            RenderPass renderPass,
            uint width, uint height,
            uint layers = 1
            )
        {
            _width      = width;
            _height     = height;
            _device     = renderPass.Device;
            _renderPass = renderPass;

            _images     = new List <Image>();
            _imageViews = new List <ImageView>();
            foreach (var attachment in renderPass.Attachments)
            {
                var img = new Image(
                    _device,
                    width, height,
                    attachment.Format,
                    attachment.ImageUsageFlags,
                    1
                    );
                _images.Add(img);
                _imageViews.Add(new ImageView(
                                    img,
                                    attachment.ImageAspectFlags
                                    ));
            }

            var attachments = new NativeList <VkImageView>();

            foreach (var view in _imageViews)
            {
                attachments.Add(view.Handle);
            }

            var framebufferCreateInfo = new VkFramebufferCreateInfo
            {
                sType           = VkStructureType.FramebufferCreateInfo,
                renderPass      = renderPass.Handle,
                attachmentCount = attachments.Count,
                pAttachments    = (VkImageView *)attachments.Data.ToPointer(),
                width           = width,
                height          = height,
                layers          = layers
            };

            VkFramebuffer framebuffer;

            if (VulkanNative.vkCreateFramebuffer(
                    _device.Handle,
                    &framebufferCreateInfo,
                    null,
                    &framebuffer
                    ) != VkResult.Success)
            {
                throw new Exception("failed to create framebuffer");
            }
            _handle = framebuffer;
        }
Пример #16
0
        private void EnableDebugCallback(VkDebugReportFlagBitsEXT flags = VkDebugReportFlagBitsEXT.VK_DEBUG_REPORT_ERROR_BIT_EXT | VkDebugReportFlagBitsEXT.VK_DEBUG_REPORT_WARNING_BIT_EXT | VkDebugReportFlagBitsEXT.VK_DEBUG_REPORT_DEBUG_BIT_EXT)
        {
            Debug.WriteLine("Enabling Vulkan Debug callbacks.");

            this.debugCallbackFunc = this.DebugCallback;
            IntPtr debugFunctionPtr = Marshal.GetFunctionPointerForDelegate(this.debugCallbackFunc);

            VkDebugReportCallbackCreateInfoEXT debugCallbackCI = new VkDebugReportCallbackCreateInfoEXT();

            debugCallbackCI.sType       = VkStructureType.VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
            debugCallbackCI.flags       = flags;
            debugCallbackCI.pfnCallback = debugFunctionPtr;

            var createFnPtr = VulkanNative.vkGetInstanceProcAddr(this.vkInstance, "vkCreateDebugReportCallbackEXT".ToPointer());

            if (createFnPtr == IntPtr.Zero)
            {
                return;
            }

            vkCreateDebugReportCallbackEXT_d createDelegate = Marshal.GetDelegateForFunctionPointer <vkCreateDebugReportCallbackEXT_d>(createFnPtr);
            VkResult result = createDelegate(this.vkInstance, &debugCallbackCI, IntPtr.Zero, out this.debugCallbackHandle);

            Helpers.CheckErrors(result);
        }
Пример #17
0
        private void CreateImageViews()
        {
            vkSwapChainImageViews = new VkImageView[vkSwapChainImages.Length];

            for (int i = 0; i < vkSwapChainImages.Length; i++)
            {
                VkImageViewCreateInfo createInfo = new VkImageViewCreateInfo()
                {
                    sType      = VkStructureType.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
                    image      = vkSwapChainImages[i],
                    viewType   = VkImageViewType.VK_IMAGE_VIEW_TYPE_2D,
                    format     = vkSwapChainImageFormat,
                    components = new VkComponentMapping()
                    {
                        r = VkComponentSwizzle.VK_COMPONENT_SWIZZLE_IDENTITY,
                        g = VkComponentSwizzle.VK_COMPONENT_SWIZZLE_IDENTITY,
                        b = VkComponentSwizzle.VK_COMPONENT_SWIZZLE_IDENTITY,
                        a = VkComponentSwizzle.VK_COMPONENT_SWIZZLE_IDENTITY,
                    },
                    subresourceRange = new VkImageSubresourceRange()
                    {
                        aspectMask     = VkImageAspectFlagBits.VK_IMAGE_ASPECT_COLOR_BIT,
                        baseMipLevel   = 0,
                        levelCount     = 1,
                        baseArrayLayer = 0,
                        layerCount     = 1
                    }
                };

                VkImageView newImageView;
                var         result = VulkanNative.vkCreateImageView(vkDevice, &createInfo, null, &newImageView);
                vkSwapChainImageViews[i] = newImageView;
                Helpers.CheckErrors(result);
            }
        }
Пример #18
0
        public string[] EnumerateInstanceLayers()
        {
            uint     propCount = 0;
            VkResult result    = VulkanNative.vkEnumerateInstanceLayerProperties(&propCount, null);

            Helpers.CheckErrors(result);

            if (propCount == 0)
            {
                return(Array.Empty <string>());
            }

            VkLayerProperties *props = stackalloc VkLayerProperties[(int)propCount];

            result = VulkanNative.vkEnumerateInstanceLayerProperties(&propCount, props);
            Helpers.CheckErrors(result);

            string[] ret = new string[propCount];
            for (int i = 0; i < propCount; i++)
            {
                ret[i] = Marshal.PtrToStringAnsi((IntPtr)props[i].layerName);
            }

            return(ret);
        }
Пример #19
0
        public unsafe DescriptorSet(DescriptorPool descriptorPool, uint setCount = 1)
        {
            _device         = descriptorPool.Device;
            _descriptorPool = descriptorPool;

            var layouts = new NativeList <VkDescriptorSetLayout>(setCount);

            for (int i = 0; i < setCount; i++)
            {
                layouts.Add(descriptorPool.Layout.Handle);
            }

            var allocateInfo = new VkDescriptorSetAllocateInfo
            {
                sType              = VkStructureType.DescriptorSetAllocateInfo,
                descriptorPool     = descriptorPool.Handle,
                descriptorSetCount = setCount,
                pSetLayouts        = (VkDescriptorSetLayout *)layouts.Data.ToPointer()
            };

            VkDescriptorSet descriptorSet;

            if (VulkanNative.vkAllocateDescriptorSets(
                    _device.Handle,
                    &allocateInfo,
                    &descriptorSet
                    ) != VkResult.Success)
            {
                throw new Exception("failed to allocate descriptor sets");
            }
            _handle = descriptorSet;
        }
Пример #20
0
        public unsafe void UpdateBuffer(Buffer buffer, int binding)
        {
            var vulkanBinding           = _descriptorPool.Layout.Bindings[binding];
            var descriptorSetBufferInfo = new VkDescriptorBufferInfo
            {
                buffer = buffer.Handle,
                offset = 0,
                range  = buffer.Size
            };

            var writeDescriptorSet = new VkWriteDescriptorSet
            {
                sType           = VkStructureType.WriteDescriptorSet,
                dstSet          = _handle,
                dstBinding      = vulkanBinding.Index,
                dstArrayElement = 0,
                descriptorCount = vulkanBinding.DescriptorCounts,
                descriptorType  = vulkanBinding.DescriptorType,
                pBufferInfo     = &descriptorSetBufferInfo,
            };

            VulkanNative.vkUpdateDescriptorSets(
                _device.Handle,
                1,
                &writeDescriptorSet,
                0,
                null
                );
        }
Пример #21
0
        private bool IsPhysicalDeviceSuitable(VkPhysicalDevice physicalDevice)
        {
            QueueFamilyIndices indices = this.FindQueueFamilies(physicalDevice);

            bool extensionsSupported = this.CheckPhysicalDeviceExtensionSupport(physicalDevice);

            // acquire Raytracing features
            VkPhysicalDeviceRayTracingFeaturesKHR rayTracingFeatures = new VkPhysicalDeviceRayTracingFeaturesKHR()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR,
                pNext = null,
            };

            VkPhysicalDeviceFeatures2 deviceFeatures2 = new VkPhysicalDeviceFeatures2()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
                pNext = &rayTracingFeatures,
            };

            VulkanNative.vkGetPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures2);

            extensionsSupported = extensionsSupported && rayTracingFeatures.rayTracing;

            bool swapChainAdequate = false;

            if (extensionsSupported)
            {
                SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(physicalDevice);
                swapChainAdequate = (swapChainSupport.formats.Length != 0 && swapChainSupport.presentModes.Length != 0);
            }

            return(indices.IsComplete() && extensionsSupported && swapChainAdequate);
        }
Пример #22
0
        public unsafe void UpdateSampledImage(ImageView view, Sampler sampler, int binding)
        {
            var vulkanBinding       = _descriptorPool.Layout.Bindings[binding];
            var descriptorImageInfo = new VkDescriptorImageInfo
            {
                imageLayout = view.Image.Layout.First(),
                imageView   = view.Handle,
                sampler     = sampler.Handle
            };

            var writeDescriptorSet = new VkWriteDescriptorSet
            {
                sType           = VkStructureType.WriteDescriptorSet,
                dstSet          = _handle,
                dstBinding      = vulkanBinding.Index,
                dstArrayElement = 0,
                descriptorCount = vulkanBinding.DescriptorCounts,
                descriptorType  = vulkanBinding.DescriptorType,
                pImageInfo      = &descriptorImageInfo
            };

            VulkanNative.vkUpdateDescriptorSets(
                _device.Handle,
                1,
                &writeDescriptorSet,
                0,
                null
                );
        }
Пример #23
0
        public unsafe SwapChainSupportDetails(VkPhysicalDevice device, VkSurfaceKHR surface)
        {
            VkSurfaceCapabilitiesKHR capabilitiesKHR;

            VulkanNative.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &capabilitiesKHR);
            capabilities = capabilitiesKHR;
            formats      = null;
            presentModes = null;

            uint formatCount;

            VulkanNative.vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, null);
            if (formatCount > 0)
            {
                formats = new VkSurfaceFormatKHR[formatCount];
                fixed(VkSurfaceFormatKHR *formatsPtr = formats)
                {
                    VulkanNative.vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, formatsPtr);
                }
            }

            uint presentModeCount;

            VulkanNative.vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, null);
            if (presentModeCount > 0)
            {
                presentModes = new VkPresentModeKHR[presentModeCount];
                fixed(VkPresentModeKHR *presentsPtr = presentModes)
                {
                    VulkanNative.vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, presentsPtr);
                }
            }
        }
Пример #24
0
        private void PickPhysicalDevice()
        {
            uint deviceCount = 0;

            Helpers.CheckErrors(VulkanNative.vkEnumeratePhysicalDevices(instance, &deviceCount, null));
            if (deviceCount == 0)
            {
                throw new Exception("Failed to find GPUs with Vulkan support!");
            }

            VkPhysicalDevice *devices = stackalloc VkPhysicalDevice[(int)deviceCount];

            Helpers.CheckErrors(VulkanNative.vkEnumeratePhysicalDevices(instance, &deviceCount, devices));

            for (int i = 0; i < deviceCount; i++)
            {
                var device = devices[i];
                if (this.IsPhysicalDeviceSuitable(device))
                {
                    this.physicalDevice = device;
                    break;
                }
            }

            if (this.physicalDevice == default)
            {
                throw new Exception("failed to find a suitable GPU!");
            }
        }
Пример #25
0
        private void GetAllInstanceExtensionsAvailables()
        {
            uint extensionCount;

            Helpers.CheckErrors(VulkanNative.vkEnumerateInstanceExtensionProperties(null, &extensionCount, null));
            VkExtensionProperties *extensions = stackalloc VkExtensionProperties[(int)extensionCount];

            Helpers.CheckErrors(VulkanNative.vkEnumerateInstanceExtensionProperties(null, &extensionCount, extensions));

            for (int i = 0; i < extensionCount; i++)
            {
                Debug.WriteLine($"Extension: {Helpers.GetString(extensions[i].extensionName)} version: {extensions[i].specVersion}");
            }

            // Return
            //Extension: VK_KHR_device_group_creation version: 1
            //Extension: VK_KHR_external_fence_capabilities version: 1
            //Extension: VK_KHR_external_memory_capabilities version: 1
            //Extension: VK_KHR_external_semaphore_capabilities version: 1
            //Extension: VK_KHR_get_physical_device_properties2 version: 2
            //Extension: VK_KHR_get_surface_capabilities2 version: 1
            //Extension: VK_KHR_surface version: 25
            //Extension: VK_KHR_surface_protected_capabilities version: 1
            //Extension: VK_KHR_win32_surface version: 6
            //Extension: VK_EXT_debug_report version: 9
            //Extension: VK_EXT_debug_utils version: 2
            //Extension: VK_EXT_swapchain_colorspace version: 4
            //Extension: VK_NV_external_memory_capabilities version: 1
        }
        private void CreateFramebuffers()
        {
            this.swapChainFramebuffers = new VkFramebuffer[this.swapChainImageViews.Length];

            for (int i = 0; i < this.swapChainImageViews.Length; i++)
            {
                VkFramebufferCreateInfo framebufferInfo = new VkFramebufferCreateInfo();
                framebufferInfo.sType           = VkStructureType.VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
                framebufferInfo.renderPass      = renderPass;
                framebufferInfo.attachmentCount = 1;

                fixed(VkImageView *attachments = &swapChainImageViews[i])
                {
                    framebufferInfo.pAttachments = attachments;
                }

                framebufferInfo.width  = swapChainExtent.width;
                framebufferInfo.height = swapChainExtent.height;
                framebufferInfo.layers = 1;

                fixed(VkFramebuffer *swapChainFramebufferPtr = &this.swapChainFramebuffers[i])
                {
                    Helpers.CheckErrors(VulkanNative.vkCreateFramebuffer(device, &framebufferInfo, null, swapChainFramebufferPtr));
                }
            }
        }
Пример #27
0
        public unsafe IntPtr GetData()
        {
            var data         = Marshal.AllocHGlobal(Convert.ToInt32(_size));
            var mappedMemory = IntPtr.Zero;

            if (VulkanNative.vkMapMemory(
                    _device.Handle,
                    _memoryHandle,
                    0,
                    _size,
                    0,
                    (void **)&mappedMemory
                    ) != VkResult.Success)
            {
                throw new Exception("failed to map device memory");
            }

            System.Buffer.MemoryCopy(
                mappedMemory.ToPointer(),
                data.ToPointer(),
                _size, _size
                );

            VulkanNative.vkUnmapMemory(_device.Handle, _memoryHandle);
            return(data);
        }
Пример #28
0
        private void CreateImageViews()
        {
            swapChainImageViews = new VkImageView[swapChainImages.Length];

            for (int i = 0; i < swapChainImages.Length; i++)
            {
                VkImageViewCreateInfo createInfo = new VkImageViewCreateInfo();
                createInfo.sType        = VkStructureType.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
                createInfo.image        = swapChainImages[i];
                createInfo.viewType     = VkImageViewType.VK_IMAGE_VIEW_TYPE_2D;
                createInfo.format       = swapChainImageFormat;
                createInfo.components.r = VkComponentSwizzle.VK_COMPONENT_SWIZZLE_IDENTITY;
                createInfo.components.g = VkComponentSwizzle.VK_COMPONENT_SWIZZLE_IDENTITY;
                createInfo.components.b = VkComponentSwizzle.VK_COMPONENT_SWIZZLE_IDENTITY;
                createInfo.components.a = VkComponentSwizzle.VK_COMPONENT_SWIZZLE_IDENTITY;
                createInfo.subresourceRange.aspectMask     = VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT;
                createInfo.subresourceRange.baseMipLevel   = 0;
                createInfo.subresourceRange.levelCount     = 1;
                createInfo.subresourceRange.baseArrayLayer = 0;
                createInfo.subresourceRange.layerCount     = 1;

                fixed(VkImageView *swapChainImageViewPtr = &swapChainImageViews[i])
                {
                    Helpers.CheckErrors(VulkanNative.vkCreateImageView(device, &createInfo, null, swapChainImageViewPtr));
                }
            }
        }
Пример #29
0
        private void CreateLogicalDevice()
        {
            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

            float priority         = 1f;
            var   queueCreateInfos = stackalloc VkDeviceQueueCreateInfo[]
            {
                new VkDeviceQueueCreateInfo()
                {
                    sType            = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
                    queueFamilyIndex = (uint)indices.GraphicsFamily,
                    queueCount       = 1,
                    pQueuePriorities = &priority,
                }
            };

            int     extensionsCount         = 1;
            IntPtr *extensionsToEnableArray = stackalloc IntPtr[extensionsCount];

            for (int i = 0; i < extensionsCount; i++)
            {
                string extension = "VK_KHR_swapchain";
                extensionsToEnableArray[i] = Marshal.StringToHGlobalAnsi(extension);
            }

            VkPhysicalDeviceFeatures deviceFeatures = new VkPhysicalDeviceFeatures();

            var createInfo = new VkDeviceCreateInfo()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
                ppEnabledExtensionNames = (byte **)extensionsToEnableArray,
                enabledExtensionCount   = (uint)extensionsCount,
                pQueueCreateInfos       = queueCreateInfos,
                queueCreateInfoCount    = 1,
                pEnabledFeatures        = &deviceFeatures,
            };

            VkDevice newDevice;
            var      result = VulkanNative.vkCreateDevice(this.vkPhysicalDevice, &createInfo, null, &newDevice);

            this.vkDevice = newDevice;
            Helpers.CheckErrors(result);

            for (int i = 0; i < extensionsCount; i++)
            {
                Marshal.FreeHGlobal(extensionsToEnableArray[i]);
            }

            VkQueue newGraphicsQueue;

            VulkanNative.vkGetDeviceQueue(vkDevice, (uint)indices.GraphicsFamily, 0, &newGraphicsQueue);
            this.vkGraphicsQueue = newGraphicsQueue;

            VkQueue newPresentQueue;

            VulkanNative.vkGetDeviceQueue(vkDevice, (uint)indices.PresentFamily, 0, &newPresentQueue);
            this.vkPresentQueue = newPresentQueue;
        }
        private void CreateCommandBuffers()
        {
            this.commandBuffers = new VkCommandBuffer[this.swapChainFramebuffers.Length];

            VkCommandBufferAllocateInfo allocInfo = new VkCommandBufferAllocateInfo()
            {
                sType              = VkStructureType.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
                commandPool        = commandPool,
                level              = VkCommandBufferLevel.VK_COMMAND_BUFFER_LEVEL_PRIMARY,
                commandBufferCount = (uint)commandBuffers.Length,
            };

            fixed(VkCommandBuffer *commandBuffersPtr = &this.commandBuffers[0])
            {
                Helpers.CheckErrors(VulkanNative.vkAllocateCommandBuffers(this.device, &allocInfo, commandBuffersPtr));
            }

            // Begin
            for (uint i = 0; i < this.commandBuffers.Length; i++)
            {
                VkCommandBufferBeginInfo beginInfo = new VkCommandBufferBeginInfo()
                {
                    sType            = VkStructureType.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
                    flags            = 0,    // Optional
                    pInheritanceInfo = null, // Optional
                };

                Helpers.CheckErrors(VulkanNative.vkBeginCommandBuffer(this.commandBuffers[i], &beginInfo));

                // Pass
                VkClearValue clearColor = new VkClearValue()
                {
                    color = new VkClearColorValue(0.0f, 0.0f, 0.0f, 1.0f),
                };

                VkRenderPassBeginInfo renderPassInfo = new VkRenderPassBeginInfo()
                {
                    sType           = VkStructureType.VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
                    renderPass      = this.renderPass,
                    framebuffer     = this.swapChainFramebuffers[i],
                    renderArea      = new VkRect2D(0, 0, this.swapChainExtent.width, this.swapChainExtent.height),
                    clearValueCount = 1,
                    pClearValues    = &clearColor,
                };

                VulkanNative.vkCmdBeginRenderPass(this.commandBuffers[i], &renderPassInfo, VkSubpassContents.VK_SUBPASS_CONTENTS_INLINE);

                // Draw
                VulkanNative.vkCmdBindPipeline(this.commandBuffers[i], VkPipelineBindPoint.VK_PIPELINE_BIND_POINT_GRAPHICS, this.graphicsPipeline);

                VulkanNative.vkCmdDraw(this.commandBuffers[i], 3, 1, 0, 0);

                VulkanNative.vkCmdEndRenderPass(this.commandBuffers[i]);

                Helpers.CheckErrors(VulkanNative.vkEndCommandBuffer(this.commandBuffers[i]));
            }
        }