예제 #1
0
        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);
        }
예제 #2
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     = 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;
            }
        }
예제 #3
0
        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();
        }
예제 #5
0
        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);
                }
            }
        }
예제 #6
0
        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!");
            }
        }
예제 #7
0
        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));
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        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));
        }
예제 #10
0
        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);
                }
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #14
0
        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);
            }
        }
예제 #15
0
        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);
            }
        }
예제 #16
0
        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!");
        }
예제 #17
0
        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());
        }
예제 #18
0
        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);
        }
예제 #19
0
        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();
        }
예제 #20
0
        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!");
            }
        }
예제 #21
0
        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);
        }
예제 #22
0
        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);
            }
        }
예제 #23
0
        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);
            }
        }
예제 #24
0
        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);
        }
예제 #25
0
        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());
        }
예제 #26
0
        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);
        }
예제 #27
0
        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);
        }
예제 #28
0
        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();
        }
예제 #29
0
        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);
        }
예제 #30
0
        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;
            }
        }
예제 #31
0
 internal static unsafe extern Result vkCreateWin32SurfaceKHR(IntPtr instance, Win32SurfaceCreateInfoKhr* pCreateInfo, Vulkan.Interop.AllocationCallbacks* pAllocator, UInt64* pSurface);