private bool checkValidationLayerSupport() { int layerCount = 0; Vulkan.vkEnumerateInstanceLayerProperties(ref layerCount, null); VkLayerProperties[] availableLayers = new VkLayerProperties[layerCount]; Vulkan.vkEnumerateInstanceLayerProperties(ref layerCount, availableLayers); foreach (var layerName in validationLayers) { bool layerFound = false; foreach (var layerProperties in availableLayers) { if (layerName == layerProperties.layerName) { layerFound = true; break; } } if (!layerFound) { return(false); } } return(true); }
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 = VkImageAspectFlagBits.VK_IMAGE_ASPECT_COLOR_BIT; createInfo.subresourceRange.baseMipLevel = 0; createInfo.subresourceRange.levelCount = 1; createInfo.subresourceRange.baseArrayLayer = 0; createInfo.subresourceRange.layerCount = 1; VkImageView imageView = null; VkResult result = Vulkan.vkCreateImageView(device, createInfo, default(VkAllocationCallbacks), out imageView); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create image views!", result); } swapChainImageViews[i] = imageView; } }
void mainLoop() { FpsCounter fpsCounter = new FpsCounter("mainLoop"); FpsCounter fpsDrawFrame = new FpsCounter("drawFrame", reportCounters: FpsReportCounters.SimpleFrameTime); FpsControl fpsControl = new FpsControl(); GLFW.EventLoop(window, () => { fpsCounter.Begin(); GLFW.glfwPollEvents(); fpsDrawFrame.Begin(); drawFrame(); fpsDrawFrame.End(); fpsCounter.End(); fpsCounter.DebugPeriodicReport(); fpsDrawFrame.DebugPeriodicReport(); fpsControl.Update(); }); Vulkan.vkDeviceWaitIdle(device); }
void cleanup() { Vulkan.vkDestroySemaphore(device, renderFinishedSemaphore, null); Vulkan.vkDestroySemaphore(device, imageAvailableSemaphore, null); Vulkan.vkDestroyCommandPool(device, commandPool, null); foreach (var framebuffer in swapChainFramebuffers) { Vulkan.vkDestroyFramebuffer(device, framebuffer, null); } Vulkan.vkDestroyPipeline(device, graphicsPipeline, null); Vulkan.vkDestroyPipelineLayout(device, pipelineLayout, null); Vulkan.vkDestroyRenderPass(device, renderPass, null); foreach (var imageView in swapChainImageViews) { Vulkan.vkDestroyImageView(device, imageView, default(VkAllocationCallbacks)); } Vulkan.vkDestroySwapchainKHR(device, swapChain, null); Vulkan.vkDestroyDevice(device, null); if (enableValidationLayers) { Vulkan.vkDestroyDebugReportCallbackEXT(instance, callback, null); } Vulkan.vkDestroySurfaceKHR(instance, surface, null); Vulkan.vkDestroyInstance(instance, null); GLFW.glfwDestroyWindow(window); GLFW.glfwTerminate(); }
public unsafe void DynamicAndStaticVkGetInstanceProcAddrGetSamePointer() { var procNames = new[] { "vkCreateInstance", "vkEnumerateInstanceLayerProperties", "vkEnumerateInstanceExtensionProperties" }.Select(Marshal.StringToCoTaskMemUTF8) .ToArray(); try { var pLib = Native.LoadLibrary("vulkan-1", "libvulkan.so", "libMoltenVK.dylib"); var pProc = Native.GetProcAddr(pLib, "vkGetInstanceProcAddr"); var vkGetInstanceProcAddr = Marshal.GetDelegateForFunctionPointer <vkGetInstanceProcAddr>(pProc); var nullVkInstance = default(VkInstance *); foreach (var procName in procNames) { var resultStatic = Vulkan.vkGetInstanceProcAddr (nullVkInstance, (sbyte *)procName); var resultDynamic = vkGetInstanceProcAddr (nullVkInstance, (sbyte *)procName); Assert.StrictEqual(resultStatic, resultDynamic); } } finally { foreach (var procName in procNames) { Marshal.FreeCoTaskMem(procName); } } }
private void pickPhysicalDevice() { int deviceCount = 0; Vulkan.vkEnumeratePhysicalDevices(instance, ref deviceCount, null); if (deviceCount == 0) { throw Program.Throw("failed to find GPUs with Vulkan support!"); } VkPhysicalDevice[] devices = new VkPhysicalDevice[deviceCount]; Vulkan.vkEnumeratePhysicalDevices(instance, ref deviceCount, devices); physicalDevice = null; foreach (var device in devices) { if (isDeviceSuitable(device)) { physicalDevice = device; break; } } if (physicalDevice == null) { throw Program.Throw("failed to find a suitable GPU!"); } }
public static unsafe ReturnSet <Instance> Create() { try { var applicationInfo = new ApplicationInfo { StructureType = StructureType.ApplicationInfo, EngineVersion = 0, ApiVersion = Vulkan.ApiVersion }; var enabledExtensionNames = BuildExtensionArray(ExtensionNames.VK_KHR_surface, ExtensionNames.VK_KHR_win32_surface, ExtensionNames.VK_EXT_debug_report); fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0]) { var instanceCreateInfo = new InstanceCreateInfo { StructureType = StructureType.InstanceCreateInfo, ApplicationInfo = new IntPtr(&applicationInfo), EnabledExtensionCount = (uint)enabledExtensionNames.Length, EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer), }; return(new ReturnSet <Instance>(Vulkan.CreateInstance(ref instanceCreateInfo))); } } catch (Exception ex) { return(new ReturnSet <Instance>(ex)); } }
public unsafe void StaticCallVkGetInstanceProcAddr() { var vkCreateInstanceStr = Marshal.StringToCoTaskMemUTF8("vkCreateInstance"); var result = Vulkan.vkGetInstanceProcAddr((VkInstance *)default(IntPtr), (sbyte *)vkCreateInstanceStr); Marshal.FreeCoTaskMem(vkCreateInstanceStr); Assert.NotStrictEqual(default(IntPtr), (IntPtr)result); }
public static VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow window, VkAllocationCallbacks pAllocator, out VkSurfaceKHR surface) { VkWin32SurfaceCreateInfoKHR pCreateInfo = new VkWin32SurfaceCreateInfoKHR(); pCreateInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; pCreateInfo.hwnd = window.GetHandle().Handle; return(Vulkan.vkCreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, out surface)); }
private void createCommandBuffers() { int commandBuffersCount = swapChainFramebuffers.Length; commandBuffers = new VkCommandBuffer[commandBuffersCount]; VkCommandBufferAllocateInfo allocInfo = new VkCommandBufferAllocateInfo(); allocInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.commandPool = commandPool; allocInfo.level = VkCommandBufferLevel.VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocInfo.commandBufferCount = commandBuffersCount; VkResult result = Vulkan.vkAllocateCommandBuffers(device, allocInfo, commandBuffers); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to allocate command buffers!", result); } for (int i = 0; i < commandBuffersCount; i++) { VkCommandBufferBeginInfo beginInfo = new VkCommandBufferBeginInfo(); beginInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.flags = VkCommandBufferUsageFlagBits.VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; Vulkan.vkBeginCommandBuffer(commandBuffers[i], beginInfo); VkRenderPassBeginInfo renderPassInfo = new VkRenderPassBeginInfo(); renderPassInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassInfo.renderPass = renderPass; renderPassInfo.framebuffer = swapChainFramebuffers[i]; renderPassInfo.renderArea.offset = VkOffset2D.Create(0, 0); renderPassInfo.renderArea.extent = swapChainExtent; VkClearValue clearColor = VkClearValue.Create(0.01f, 0.03f, 0.01f, 1.0f); renderPassInfo.clearValueCount = 1; renderPassInfo.pClearValues = new VkClearValue[] { clearColor }; Vulkan.vkCmdBeginRenderPass(commandBuffers[i], renderPassInfo, VkSubpassContents.VK_SUBPASS_CONTENTS_INLINE); Vulkan.vkCmdBindPipeline(commandBuffers[i], VkPipelineBindPoint.VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); VkBuffer[] vertexBuffers = new VkBuffer[] { vertexBuffer }; int[] offsets = new int[] { 0 }; Vulkan.vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, vertexBuffers, offsets); Vulkan.vkCmdDraw(commandBuffers[i], vertices.Length, 1, 0, 0); Vulkan.vkCmdEndRenderPass(commandBuffers[i]); result = Vulkan.vkEndCommandBuffer(commandBuffers[i]); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to record command buffer!", result); } } }
private void createLogicalDevice() { QueueFamilyIndices indices = findQueueFamilies(physicalDevice); List <VkDeviceQueueCreateInfo> queueCreateInfos = new List <VkDeviceQueueCreateInfo>(); HashSet <int> uniqueQueueFamilies = new HashSet <int>() { indices.graphicsFamily, indices.presentFamily }; float[] queuePriorities = new float[] { 1.0f }; foreach (var queueFamily in uniqueQueueFamilies) { VkDeviceQueueCreateInfo queueCreateInfo = new VkDeviceQueueCreateInfo(); queueCreateInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueCreateInfo.queueFamilyIndex = queueFamily; queueCreateInfo.queueCount = 1; queueCreateInfo.pQueuePriorities = queuePriorities; queueCreateInfos.Add(queueCreateInfo); } VkPhysicalDeviceFeatures deviceFeatures = new VkPhysicalDeviceFeatures(); VkDeviceCreateInfo createInfo = new VkDeviceCreateInfo(); createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.queueCreateInfoCount = queueCreateInfos.Count; createInfo.pQueueCreateInfos = queueCreateInfos.ToArray(); createInfo.pEnabledFeatures = new VkPhysicalDeviceFeatures[] { deviceFeatures }; createInfo.enabledExtensionCount = deviceExtensions.Length; createInfo.ppEnabledExtensionNames = deviceExtensions; if (enableValidationLayers) { createInfo.enabledLayerCount = validationLayers.Length; createInfo.ppEnabledLayerNames = validationLayers; } else { createInfo.enabledLayerCount = 0; } VkResult result = Vulkan.vkCreateDevice(physicalDevice, createInfo, null, out device); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create logical device!", result); } Vulkan.vkGetDeviceQueue(device, indices.graphicsFamily, 0, out graphicsQueue); Vulkan.vkGetDeviceQueue(device, indices.presentFamily, 0, out presentQueue); }
void createSemaphores() { VkSemaphoreCreateInfo semaphoreInfo = new VkSemaphoreCreateInfo(); semaphoreInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; if (Vulkan.vkCreateSemaphore(device, semaphoreInfo, null, out imageAvailableSemaphore) != VkResult.VK_SUCCESS || Vulkan.vkCreateSemaphore(device, semaphoreInfo, null, out renderFinishedSemaphore) != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create semaphores!"); } }
void drawFrame() { int imageIndex; Vulkan.vkAcquireNextImageKHR(device, swapChain, long.MaxValue, imageAvailableSemaphore, null, out imageIndex); VkSubmitInfo submitInfo = new VkSubmitInfo(); submitInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SUBMIT_INFO; VkSemaphore[] waitSemaphores = new VkSemaphore[] { imageAvailableSemaphore }; VkPipelineStageFlagBits[] waitStages = new VkPipelineStageFlagBits[] { VkPipelineStageFlagBits.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = new VkCommandBuffer[] { commandBuffers[imageIndex] }; VkSemaphore[] signalSemaphores = new VkSemaphore[] { renderFinishedSemaphore }; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; fpsSubmitQueue.Begin(); VkResult result = Vulkan.vkQueueSubmit(graphicsQueue, 1, new VkSubmitInfo[] { submitInfo }, null); fpsSubmitQueue.End(); fpsSubmitQueue.DebugPeriodicReport(); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to submit draw command buffer!"); } VkPresentInfoKHR presentInfo = new VkPresentInfoKHR(); presentInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = 1; presentInfo.pWaitSemaphores = signalSemaphores; VkSwapchainKHR[] swapChains = new VkSwapchainKHR[] { swapChain }; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = swapChains; presentInfo.pImageIndices = new int[] { imageIndex }; fpsPresentQueue.Begin(); Vulkan.vkQueuePresentKHR(presentQueue, presentInfo); fpsPresentQueue.End(); fpsPresentQueue.DebugPeriodicReport(); Vulkan.vkQueueWaitIdle(presentQueue); }
public void createRenderPass() { VkAttachmentDescription colorAttachment = new VkAttachmentDescription(); colorAttachment.format = swapChainImageFormat; colorAttachment.samples = VkSampleCountFlagBits.VK_SAMPLE_COUNT_1_BIT; colorAttachment.loadOp = VkAttachmentLoadOp.VK_ATTACHMENT_LOAD_OP_CLEAR; colorAttachment.storeOp = VkAttachmentStoreOp.VK_ATTACHMENT_STORE_OP_STORE; colorAttachment.stencilLoadOp = VkAttachmentLoadOp.VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorAttachment.stencilStoreOp = VkAttachmentStoreOp.VK_ATTACHMENT_STORE_OP_DONT_CARE; colorAttachment.initialLayout = VkImageLayout.VK_IMAGE_LAYOUT_UNDEFINED; colorAttachment.finalLayout = VkImageLayout.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; VkAttachmentReference colorAttachmentRef = new VkAttachmentReference(); colorAttachmentRef.attachment = 0; colorAttachmentRef.layout = VkImageLayout.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; VkSubpassDescription subpass = new VkSubpassDescription(); subpass.pipelineBindPoint = VkPipelineBindPoint.VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachmentCount = 1; subpass.pColorAttachments = new VkAttachmentReference[] { colorAttachmentRef }; VkSubpassDependency dependency = new VkSubpassDependency(); dependency.srcSubpass = Vulkan.VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VkPipelineStageFlagBits.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.srcAccessMask = 0; dependency.dstStageMask = VkPipelineStageFlagBits.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.dstAccessMask = VkAccessFlagBits.VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VkAccessFlagBits.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; VkRenderPassCreateInfo renderPassInfo = new VkRenderPassCreateInfo(); renderPassInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassInfo.attachmentCount = 1; renderPassInfo.pAttachments = new VkAttachmentDescription[] { colorAttachment }; renderPassInfo.subpassCount = 1; renderPassInfo.pSubpasses = new VkSubpassDescription[] { subpass }; renderPassInfo.dependencyCount = 1; renderPassInfo.pDependencies = new VkSubpassDependency[] { dependency }; VkResult result = Vulkan.vkCreateRenderPass(device, renderPassInfo, null, out renderPass); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create render pass!", result); } }
private void createCommandPool() { QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice); VkCommandPoolCreateInfo poolInfo = new VkCommandPoolCreateInfo(); poolInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily; VkResult result = Vulkan.vkCreateCommandPool(device, poolInfo, null, out commandPool); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create command pool!", result); } }
private int findMemoryType(int typeFilter, VkMemoryPropertyFlagBits properties) { VkPhysicalDeviceMemoryProperties memProperties; Vulkan.vkGetPhysicalDeviceMemoryProperties(physicalDevice, out memProperties); for (int i = 0; i < memProperties.memoryTypeCount; i++) { if ((typeFilter & (1 << i)) != 0 && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) { return(i); } } throw new Exception("failed to find suitable memory type!"); }
private bool checkDeviceExtensionsSupport(VkPhysicalDevice physicalDevice) { int extensionCount = 0; Vulkan.vkEnumerateDeviceExtensionProperties(physicalDevice, null, ref extensionCount, null); VkExtensionProperties[] availableExtensions = new VkExtensionProperties[extensionCount]; Vulkan.vkEnumerateDeviceExtensionProperties(physicalDevice, null, ref extensionCount, availableExtensions); HashSet <string> requiredExtensions = new HashSet <string>(deviceExtensions); foreach (var extension in availableExtensions) { requiredExtensions.Remove(extension.extensionName); } return(!requiredExtensions.Any()); }
internal Instance(string appName, string engName, VER appVer, VER engVer, VER apiVer, bool bDebug) { string vlName = ""; if (bDebug) { if (!bCheckValidation(out vlName)) { return; } } ApplicationInfo ai = new ApplicationInfo(); ai.ApplicationName = appName; ai.ApplicationVersion = appVer; ai.EngineName = engName; ai.EngineVersion = engVer; ai.ApiVersion = apiVer; InstanceCreateInfo ici = new InstanceCreateInfo(); ici.Next = IntPtr.Zero; ici.ApplicationInfo = ai; List <string> extensions = new List <string>(); extensions.AddRange(Vulkan.GetRequiredInstanceExtensions()); if (bDebug) { extensions.Add(Constant.InstanceExtension.ExtDebugReport); } //get extension stuff from glfw ici.EnabledExtensionNames = extensions.ToArray(); if (bDebug) { ici.EnabledLayerNames = new string[1] { vlName }; } mInstance = new INST(ici, null); }
void cleanup() { cleanupSwapChain(); Vulkan.vkDestroySemaphore(device, renderFinishedSemaphore, null); Vulkan.vkDestroySemaphore(device, imageAvailableSemaphore, null); Vulkan.vkDestroyCommandPool(device, commandPool, null); Vulkan.vkDestroyDevice(device, null); Vulkan.vkDestroyDebugReportCallbackEXT(instance, callback, null); Vulkan.vkDestroySurfaceKHR(instance, surface, null); Vulkan.vkDestroyInstance(instance, null); GLFW.glfwDestroyWindow(window); GLFW.glfwTerminate(); }
private void setupDebugCallback() { if (!enableValidationLayers) { return; } VkDebugReportCallbackCreateInfoEXT createInfo = new VkDebugReportCallbackCreateInfoEXT(); createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; createInfo.flags = VkDebugReportFlagBitsEXT.VK_DEBUG_REPORT_ERROR_BIT_EXT | VkDebugReportFlagBitsEXT.VK_DEBUG_REPORT_WARNING_BIT_EXT; createInfo.pfnCallback = debugCallback; if (Vulkan.vkCreateDebugReportCallbackEXT(instance, createInfo, null, out callback) != VkResult.VK_SUCCESS) { throw Program.Throw("failed to set up debug callback!"); } }
private VkShaderModule createShaderModule(Type shaderCode) { VkShaderModuleCreateInfo createInfo = new VkShaderModuleCreateInfo(); createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; createInfo.pCode = shaderCode; VkShaderModule shaderModule = null; VkResult result; result = Vulkan.vkCreateShaderModule(device, createInfo, default(VkAllocationCallbacks), out shaderModule); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create shader module!", result); } return(shaderModule); }
public unsafe void Utf8StringStaticVkGetInstanceProcAddr() { var procNames = new[] { "vkCreateInstance", "vkEnumerateInstanceLayerProperties", "vkEnumerateInstanceExtensionProperties" }.Select(s => new Utf8String(s)) .ToArray(); var nullVkInstance = (VkInstance *)default(IntPtr); foreach (var procName in procNames) { var resultStatic = Vulkan.vkGetInstanceProcAddr (nullVkInstance, procName.Pointer); Assert.NotStrictEqual(default(IntPtr), (IntPtr)resultStatic); } }
private void createInstance() { if (enableValidationLayers && !checkValidationLayerSupport()) { throw Program.Throw("validation layers requested, but not available"); } VkApplicationInfo appInfo = new VkApplicationInfo(); appInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Hello Triangle"; appInfo.applicationVersion = Vulkan.VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "No Engine"; appInfo.engineVersion = Vulkan.VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VkApiVersion.VK_API_VERSION_1_0; VkInstanceCreateInfo createInfo = new VkInstanceCreateInfo(); createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = appInfo; List <string> extensions = getRequiredExtensions(); createInfo.enabledExtensionCount = extensions.Count; createInfo.ppEnabledExtensionNames = extensions.ToArray(); if (enableValidationLayers) { createInfo.enabledLayerCount = validationLayers.Length; createInfo.ppEnabledLayerNames = validationLayers; } else { createInfo.enabledLayerCount = 0; } VkResult result = Vulkan.vkCreateInstance(createInfo, null, out instance); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create instance!", result); } }
void cleanupSwapChain() { foreach (var framebuffer in swapChainFramebuffers) { Vulkan.vkDestroyFramebuffer(device, framebuffer, null); } Vulkan.vkFreeCommandBuffers(device, commandPool, commandBuffers.Length, commandBuffers); Vulkan.vkDestroyPipeline(device, graphicsPipeline, null); Vulkan.vkDestroyPipelineLayout(device, pipelineLayout, null); Vulkan.vkDestroyRenderPass(device, renderPass, null); foreach (var imageView in swapChainImageViews) { Vulkan.vkDestroyImageView(device, imageView, null); } Vulkan.vkDestroySwapchainKHR(device, swapChain, null); }
internal void CreateWindowSurface(Window wnd) { //create window surface IntPtr surfaceHandle; Result result = (Result)Vulkan.CreateWindowSurface( mInstance.GetInstance().Handle, wnd, IntPtr.Zero, out surfaceHandle); if (result != Result.Success) { ErrorSpew("Window surface creation failed: " + result.ToString()); return; } AllocationCallbacks?superAnnoyingParameter = null; mSurface = new SurfaceKhr(mInstance.GetInstance(), ref superAnnoyingParameter, surfaceHandle.ToInt64()); }
private SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice physicalDevice) { SwapChainSupportDetails details; Vulkan.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, out details.capabilities); int formatCount = 0; Vulkan.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, ref formatCount, null); details.formats = new VkSurfaceFormatKHR[formatCount]; Vulkan.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, ref formatCount, details.formats); int presentModeCount = 0; Vulkan.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, ref presentModeCount, null); details.presentModes = new VkPresentModeKHR[presentModeCount]; Vulkan.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, ref presentModeCount, details.presentModes); return(details); }
private void createVertexBuffer() { VkBufferCreateInfo bufferInfo = new VkBufferCreateInfo(); bufferInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferInfo.size = Marshal.SizeOf(vertices[0]) * vertices.Length; bufferInfo.usage = VkBufferUsageFlagBits.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; bufferInfo.sharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE; VkResult result = Vulkan.vkCreateBuffer(device, bufferInfo, null, out vertexBuffer); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create vertex buffer!", result); } VkMemoryRequirements memRequirements; Vulkan.vkGetBufferMemoryRequirements(device, vertexBuffer, out memRequirements); VkMemoryAllocateInfo allocInfo = new VkMemoryAllocateInfo(); allocInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.allocationSize = memRequirements.size; allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VkMemoryPropertyFlagBits.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlagBits.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); result = Vulkan.vkAllocateMemory(device, allocInfo, null, out vertexBufferMemory); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to allocate vertex buffer memory!", result); } Vulkan.vkBindBufferMemory(device, vertexBuffer, vertexBufferMemory, 0); byte[] data; Vulkan.vkMapMemory(device, vertexBufferMemory, 0, bufferInfo.size, 0, out data); MemoryCopyHelper.Copy(vertices, data, 0, bufferInfo.size); Vulkan.vkUnmapMemory(device, vertexBufferMemory); }
void recreateSwapChain() { int width, height; GLFW.glfwGetWindowSize(window, out width, out height); if (width == 0 || height == 0) { return; } Vulkan.vkDeviceWaitIdle(device); cleanupSwapChain(); createSwapChain(); createImageViews(); createRenderPass(); createGraphicsPipeline(); createFramebuffers(); createCommandBuffers(); }
private QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) { QueueFamilyIndices indices = new QueueFamilyIndices(); int queueFamilyCount = 0; Vulkan.vkGetPhysicalDeviceQueueFamilyProperties(device, ref queueFamilyCount, null); VkQueueFamilyProperties[] queueFamilies = new VkQueueFamilyProperties[queueFamilyCount]; Vulkan.vkGetPhysicalDeviceQueueFamilyProperties(device, ref queueFamilyCount, queueFamilies); int i = 0; foreach (var queueFamily in queueFamilies) { if (queueFamily.queueCount > 0 && (queueFamily.queueFlags & VkQueueFlagBits.VK_QUEUE_GRAPHICS_BIT) > 0) { indices.graphicsFamily = i; } bool presentSupport = false; Vulkan.vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, out presentSupport); if (queueFamily.queueCount > 0 && presentSupport) { indices.presentFamily = i; } if (indices.isComplete()) { break; } i++; } return(indices); }
private void createFramebuffers() { swapChainFramebuffers = new VkFramebuffer[swapChainImageViews.Length]; for (int i = 0; i < swapChainImageViews.Length; i++) { VkFramebufferCreateInfo framebufferInfo = new VkFramebufferCreateInfo(); framebufferInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.renderPass = renderPass; framebufferInfo.attachmentCount = 1; framebufferInfo.pAttachments = new VkImageView[] { swapChainImageViews[i] }; framebufferInfo.width = swapChainExtent.width; framebufferInfo.height = swapChainExtent.height; framebufferInfo.layers = 1; VkFramebuffer frameBuffer = null; VkResult result = Vulkan.vkCreateFramebuffer(device, framebufferInfo, null, out frameBuffer); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create framebuffer!", result); } swapChainFramebuffers[i] = frameBuffer; } }
internal static unsafe extern Result vkCreateWin32SurfaceKHR(IntPtr instance, Win32SurfaceCreateInfoKhr* pCreateInfo, Vulkan.Interop.AllocationCallbacks* pAllocator, UInt64* pSurface);