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()); }
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; }
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]); }
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()); }
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 ); } }
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"); } }
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, ®ion ); }
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); }
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; } }
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; }
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(); }
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 )); }
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); }
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); } }
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; }
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); }
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); } }
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); }
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; }
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 ); }
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); }
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 ); }
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); } } }
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!"); } }
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)); } } }
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); }
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)); } } }
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])); } }