示例#1
0
 public FrameBuffer(GraphicsDevice device, RenderPass renderPass, DepthStencil depthStencil, Swapchain swapchain, uint swapchainImageIndex)
 {
     this.device              = device;
     this.renderPass          = renderPass;
     this.depthStencil        = depthStencil;
     this.swapchain           = swapchain;
     this.swapchainImageIndex = swapchainImageIndex;
     Setup();
 }
        public static RenderPass Single(GraphicsDevice device, Swapchain swapchain = null)
        {
            if (swapchain == null)
            {
                swapchain = device.mainSwapchain;
            }
            RenderPass newPass = new RenderPass(device);

            newPass.SetupSinglePass(swapchain);

            return(newPass);
        }
        public static RenderPass ClearTargetsPass(GraphicsDevice device, Swapchain swapchain = null)
        {
            if (swapchain == null)
            {
                swapchain = device.mainSwapchain;
            }
            RenderPass newPass = new RenderPass(device);

            newPass.SetupClearAttachmentsPass(swapchain);

            return(newPass);
        }
示例#4
0
        public CommandPool(GraphicsDevice device, Swapchain swapchain)
        {
            this.device = device;

            VkCommandPoolCreateInfo cmdPoolInfo = VkCommandPoolCreateInfo.New();

            cmdPoolInfo.queueFamilyIndex = swapchain.vkSwapchain.QueueNodeIndex;
            cmdPoolInfo.flags            =
                VkCommandPoolCreateFlags.ResetCommandBuffer
                | VkCommandPoolCreateFlags.Transient;
            Util.CheckResult(vkCreateCommandPool(device.device, &cmdPoolInfo, null, out vkCmdPool));

            AllocateBuffers(VkCommandBufferLevel.Primary, 2);
            AllocateBuffers(VkCommandBufferLevel.Secondary, 2);
        }
示例#5
0
        /// <summary>
        /// Must be called outside of a renderpass scope.
        /// </summary>
        /// <param name="depthStencil"></param>
        /// <param name="clearValue"></param>
        public void ClearColor(Swapchain swapchain, uint swapchainImageIndex, VkClearColorValue clearColor)
        {
            CheckBegun();
            CheckNotInRenderPass();

            VkClearValue clearValue = new VkClearValue();

            clearValue.color = clearColor;

            VkImageSubresourceRange imageRange = new VkImageSubresourceRange();

            imageRange.aspectMask = VkImageAspectFlags.Color;
            imageRange.levelCount = 1;
            imageRange.layerCount = 1;
            vkCmdClearColorImage(vkCmd, swapchain.vkSwapchain.Images[swapchainImageIndex], VkImageLayout.General, &clearColor, 1, &imageRange);
        }
        public GraphicsDevice(bool enableValidation)
        {
            VkResult err;

            err = CreateInstance("VulkanDevice", enableValidation);
            if (err != VkResult.Success)
            {
                throw new InvalidOperationException("Could not create Vulkan instance. Error: " + err);
            }

            // Physical Device
            uint gpuCount = 0;

            Util.CheckResult(vkEnumeratePhysicalDevices(Instance, &gpuCount, null));
            Debug.Assert(gpuCount > 0);

            // Enumerate devices
            IntPtr *physicalDevices = stackalloc IntPtr[(int)gpuCount];

            err = vkEnumeratePhysicalDevices(Instance, &gpuCount, (VkPhysicalDevice *)physicalDevices);
            if (err != VkResult.Success)
            {
                throw new InvalidOperationException("Could not enumerate physical devices.");
            }

            // GPU selection

            uint selectedDevice           = 0;
            VkPhysicalDeviceType bestType = VkPhysicalDeviceType.Other;
            ulong bestDeviceLocalMemSize  = 0;

            for (uint i = 0; i < gpuCount; i++)
            {
                VkPhysicalDevice           device = ((VkPhysicalDevice *)physicalDevices)[i];
                VkPhysicalDeviceProperties devProps;
                vkGetPhysicalDeviceProperties(device, &devProps);


                if (devProps.deviceType == VkPhysicalDeviceType.IntegratedGpu &&
                    bestType != VkPhysicalDeviceType.IntegratedGpu &&
                    bestType != VkPhysicalDeviceType.DiscreteGpu)
                {
                    selectedDevice         = i;
                    bestType               = VkPhysicalDeviceType.IntegratedGpu;
                    bestDeviceLocalMemSize = GetDeviceLocalMemorySize(device);
                }
                else if (devProps.deviceType == VkPhysicalDeviceType.DiscreteGpu &&
                         bestType != VkPhysicalDeviceType.DiscreteGpu)
                {
                    //Found a discrete GPU, we can choose it.
                    selectedDevice         = i;
                    bestType               = VkPhysicalDeviceType.DiscreteGpu;
                    bestDeviceLocalMemSize = GetDeviceLocalMemorySize(device);
                }
                else if (devProps.deviceType == VkPhysicalDeviceType.DiscreteGpu &&
                         bestType == VkPhysicalDeviceType.DiscreteGpu)
                {
                    ulong memSize = GetDeviceLocalMemorySize(device);
                    if (memSize > bestDeviceLocalMemSize)
                    {
                    }
                    selectedDevice         = i;
                    bestType               = VkPhysicalDeviceType.DiscreteGpu;
                    bestDeviceLocalMemSize = memSize;
                }
            }

            Console.WriteLine($"Found a vulkan capable GPU of type {bestType} at location {selectedDevice}. With {bestDeviceLocalMemSize / (1024 * 1024)}MiB of memory.");
            // Select physical Device to be used for the Vulkan example
            // Defaults to the first Device unless specified by command line


            // TODO: Implement arg parsing, etc.



            physicalDevice = ((VkPhysicalDevice *)physicalDevices)[selectedDevice];

            Console.WriteLine(PrintDeviceMemoryData(physicalDevice));


            // Store properties (including limits) and features of the phyiscal Device
            // So examples can check against them and see if a feature is actually supported
            VkPhysicalDeviceProperties deviceProperties;

            vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
            DeviceProperties = deviceProperties;

            VkPhysicalDeviceFeatures deviceFeatures;

            vkGetPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
            DeviceFeatures = deviceFeatures;

            // Gather physical Device memory properties
            VkPhysicalDeviceMemoryProperties deviceMemoryProperties;

            vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties);
            DeviceMemoryProperties = deviceMemoryProperties;

            // Derived examples can override this to set actual features (based on above readings) to enable for logical device creation
            //getEnabledFeatures();

            // Vulkan Device creation
            // This is handled by a separate class that gets a logical Device representation
            // and encapsulates functions related to a Device
            vulkanDevice = new vksVulkanDevice(physicalDevice);
            VkResult res = vulkanDevice.CreateLogicalDevice(enabledFeatures, EnabledExtensions);

            if (res != VkResult.Success)
            {
                throw new InvalidOperationException("Could not create Vulkan Device.");
            }
            device = vulkanDevice.LogicalDevice;

            // Get a graphics queue from the Device
            VkQueue queue;

            vkGetDeviceQueue(device, vulkanDevice.QFIndices.Graphics, 0, &queue);
            this.queue = queue;

            // Find a suitable depth format
            VkFormat depthFormat;
            uint     validDepthFormat = Tools.GetSupportedDepthFormat(physicalDevice, &depthFormat);

            Debug.Assert(validDepthFormat == True);
            DepthFormat = depthFormat;

            mainSwapchain = new Swapchain(this);
            mainSwapchain.Connect(Instance, physicalDevice, device);

            // Create synchronization objects
            VkSemaphoreCreateInfo semaphoreCreateInfo = Initializers.semaphoreCreateInfo();

            // Create a semaphore used to synchronize image presentation
            // Ensures that the image is displayed before we start submitting new commands to the queu
            Util.CheckResult(vkCreateSemaphore(device, &semaphoreCreateInfo, null, &GetSemaphoresPtr()->PresentComplete));
            // Create a semaphore used to synchronize command submission
            // Ensures that the image is not presented until all commands have been sumbitted and executed
            Util.CheckResult(vkCreateSemaphore(device, &semaphoreCreateInfo, null, &GetSemaphoresPtr()->RenderComplete));
            // Create a semaphore used to synchronize command submission
            // Ensures that the image is not presented until all commands for the text overlay have been sumbitted and executed
            // Will be inserted after the render complete semaphore if the text overlay is enabled
            Util.CheckResult(vkCreateSemaphore(device, &semaphoreCreateInfo, null, &GetSemaphoresPtr()->TextOverlayComplete));

            // Set up submit info structure
            // Semaphores will stay the same during application lifetime
            // Command buffer submission info is set by each example
            submitInfo = Initializers.SubmitInfo();
            submitInfo.pWaitDstStageMask    = (VkPipelineStageFlags *)submitPipelineStages.Data;
            submitInfo.waitSemaphoreCount   = 1;
            submitInfo.pWaitSemaphores      = &GetSemaphoresPtr()->PresentComplete;
            submitInfo.signalSemaphoreCount = 1;
            submitInfo.pSignalSemaphores    = &GetSemaphoresPtr()->RenderComplete;

            memoryAllocator = new VulkanMemoryAllocator(this);
        }
示例#7
0
 public DepthStencil(GraphicsDevice device, Swapchain swapchain)
 {
     this.device    = device;
     this.swapchain = swapchain;
     Setup();
 }
        private void SetupClearAttachmentsPass(Swapchain swapchain)
        {
            using (NativeList <VkAttachmentDescription> attachments = new NativeList <VkAttachmentDescription>())
            {
                attachments.Count = 2;
                // Color attachment
                attachments[0]                = new VkAttachmentDescription();
                attachments[0].format         = swapchain.vkSwapchain.ColorFormat;
                attachments[0].samples        = VkSampleCountFlags.Count1;
                attachments[0].loadOp         = VkAttachmentLoadOp.Clear;
                attachments[0].storeOp        = VkAttachmentStoreOp.Store;
                attachments[0].stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                attachments[0].stencilStoreOp = VkAttachmentStoreOp.DontCare;
                attachments[0].initialLayout  = VkImageLayout.Undefined;
                attachments[0].finalLayout    = VkImageLayout.ColorAttachmentOptimal; //TODO
                // Depth attachment
                attachments[1]                = new VkAttachmentDescription();
                attachments[1].format         = device.DepthFormat;
                attachments[1].samples        = VkSampleCountFlags.Count1;
                attachments[1].loadOp         = VkAttachmentLoadOp.Clear;
                attachments[1].storeOp        = VkAttachmentStoreOp.Store;
                attachments[1].stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                attachments[1].stencilStoreOp = VkAttachmentStoreOp.DontCare;
                attachments[1].initialLayout  = VkImageLayout.Undefined;
                attachments[1].finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal;

                VkAttachmentReference colorReference = new VkAttachmentReference();
                colorReference.attachment = 0;
                colorReference.layout     = VkImageLayout.ColorAttachmentOptimal;

                VkAttachmentReference depthReference = new VkAttachmentReference();
                depthReference.attachment = 1;
                depthReference.layout     = VkImageLayout.DepthStencilAttachmentOptimal;

                VkSubpassDescription subpassDescription = new VkSubpassDescription();
                subpassDescription.pipelineBindPoint       = VkPipelineBindPoint.Graphics;
                subpassDescription.colorAttachmentCount    = 1;
                subpassDescription.pColorAttachments       = &colorReference;
                subpassDescription.pDepthStencilAttachment = &depthReference;
                subpassDescription.inputAttachmentCount    = 0;
                subpassDescription.pInputAttachments       = null;
                subpassDescription.preserveAttachmentCount = 0;
                subpassDescription.pPreserveAttachments    = null;
                subpassDescription.pResolveAttachments     = null;

                // Subpass dependencies for layout transitions
                using (NativeList <VkSubpassDependency> dependencies = new NativeList <VkSubpassDependency>(2))
                {
                    dependencies.Count = 2;

                    dependencies[0].srcSubpass      = SubpassExternal;
                    dependencies[0].dstSubpass      = 0;
                    dependencies[0].srcStageMask    = VkPipelineStageFlags.BottomOfPipe;
                    dependencies[0].dstStageMask    = VkPipelineStageFlags.ColorAttachmentOutput;
                    dependencies[0].srcAccessMask   = VkAccessFlags.MemoryRead;
                    dependencies[0].dstAccessMask   = (VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite);
                    dependencies[0].dependencyFlags = VkDependencyFlags.ByRegion;

                    dependencies[1].srcSubpass      = 0;
                    dependencies[1].dstSubpass      = SubpassExternal;
                    dependencies[1].srcStageMask    = VkPipelineStageFlags.ColorAttachmentOutput;
                    dependencies[1].dstStageMask    = VkPipelineStageFlags.BottomOfPipe;
                    dependencies[1].srcAccessMask   = (VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite);
                    dependencies[1].dstAccessMask   = VkAccessFlags.MemoryRead;
                    dependencies[1].dependencyFlags = VkDependencyFlags.ByRegion;

                    VkRenderPassCreateInfo renderPassInfo = new VkRenderPassCreateInfo();
                    renderPassInfo.sType           = VkStructureType.RenderPassCreateInfo;
                    renderPassInfo.attachmentCount = attachments.Count;
                    renderPassInfo.pAttachments    = (VkAttachmentDescription *)attachments.Data.ToPointer();
                    renderPassInfo.subpassCount    = 1;
                    renderPassInfo.pSubpasses      = &subpassDescription;
                    renderPassInfo.dependencyCount = dependencies.Count;
                    renderPassInfo.pDependencies   = (VkSubpassDependency *)dependencies.Data;

                    Util.CheckResult(vkCreateRenderPass(device.device, &renderPassInfo, null, out vkRenderPass));
                }
            }
        }