예제 #1
0
        public void InitializeVulkan()
        {
            // Create the VUlkan instance that we will use for this app
            _Instance = new VkInstance("Triangle - Sample", 1, "Ratchet", 1);


            // Now lets walk all physical device and find the first one that supports graphics queue
            foreach (VkPhysicalDevice physicalDevice in _Instance.vkEnumeratePhysicalDevices())
            {
                foreach (VkQueueFamilyProperties queueFamilly in physicalDevice.QueueFamilies)
                {
                    if ((queueFamilly.queueFlags & VkQueueFlags.VK_QUEUE_GRAPHICS) != 0)
                    {
                        // We have a physical device that supports graphics queue, we can now create a Device on it
                        // with one queue and use it as our main device for this sample
                        _Device = physicalDevice.CreateDevice(new VkDeviceQueueCreateInfo[] { new VkDeviceQueueCreateInfo()
                                                                                              {
                                                                                                  queueCount = 1, queueFamily = queueFamilly, queuePriorities = new float[] { 1.0f }
                                                                                              } });

                        // Ok now lets grab the graphics queue back. Technically there should only be one
                        // But just to be clean we do an iteration and look for the queue that matches our
                        // need
                        foreach (VkQueue queue in _Device.Queues)
                        {
                            if (queue.Family.queueFlags == queueFamilly.queueFlags)
                            {
                                _Queue = queue;
                                break;
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        /**
         * Finish command buffer recording and submit it to a queue
         *
         * @param commandBuffer Command buffer to flush
         * @param queue Queue to submit the command buffer to
         * @param free (Optional) Free the command buffer once it has been submitted (Defaults to true)
         *
         * @note The queue that the command buffer is submitted to must be from the same family index as the pool it was allocated from
         * @note Uses a fence to ensure command buffer has finished executing
         */
        public void flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, bool free = true)
        {
            if (commandBuffer.handle == 0)
            {
                return;
            }

            vkEndCommandBuffer(commandBuffer);

            VkSubmitInfo submitInfo = new VkSubmitInfo();

            submitInfo.sType          = SubmitInfo;
            submitInfo.commandBuffers = commandBuffer;

            // Create fence to ensure that the command buffer has finished executing
            VkFenceCreateInfo fenceInfo = new VkFenceCreateInfo();

            fenceInfo.sType = FenceCreateInfo;
            fenceInfo.flags = 0;
            VkFence fence;

            vkCreateFence(_logicalDevice, &fenceInfo, null, &fence);

            // Submit to the queue
            vkQueueSubmit(queue, 1, &submitInfo, fence);
            // Wait for the fence to signal that command buffer has finished executing
            vkWaitForFences(_logicalDevice, 1, &fence, true, DEFAULT_FENCE_TIMEOUT);

            vkDestroyFence(_logicalDevice, fence, null);

            if (free)
            {
                vkFreeCommandBuffers(_logicalDevice, CommandPool, 1, &commandBuffer);
            }
        }
예제 #3
0
        public void Submit(CommandBuffer buffer, VkSemaphore?wait = null, VkPipelineStageFlag waitStage = 0,
                           VkSemaphore?signal = null,
                           VkFence?submit     = null)
        {
            buffer.AssertBuilt();
            var buff = buffer.Handle;

            unsafe
            {
                var waitH   = wait ?? VkSemaphore.Null;
                var signalH = signal ?? VkSemaphore.Null;
                var submitH = submit ?? VkFence.Null;
                var info    = new VkSubmitInfo()
                {
                    SType = VkStructureType.SubmitInfo,
                    PNext = IntPtr.Zero,
                    CommandBufferCount   = 1,
                    PCommandBuffers      = &buff,
                    SignalSemaphoreCount = signalH != VkSemaphore.Null ? 1u : 0u,
                    PSignalSemaphores    = &signalH,
                    WaitSemaphoreCount   = waitH != VkSemaphore.Null ? 1u : 0u,
                    PWaitSemaphores      = &waitH,
                    PWaitDstStageMask    = &waitStage,
                };
                if (buffer is CommandBufferPooledExclusiveUse peu)
                {
                    Debug.Assert(submitH == VkFence.Null, "Can't use a submit fence on a pooled handle");
                    peu.DoSubmit(Handle, info);
                }
                else
                {
                    VkException.Check(VkQueue.vkQueueSubmit(Handle, 1, &info, submitH));
                }
            }
        }
예제 #4
0
        public void Render()
        {
            if (!isInitialized)
            {
                return;
            }

            if (this.submitInfos == null)
            {
                InitRenderParams();
            }

            VkDevice    device = this.device; VkSwapchainKHR swapchain = this.swapchain;
            VkSemaphore semaphore = this.vkSemaphore; VkFence fence = this.vkFence;
            VkQueue     queue = this.vkQueue;
            //uint nextIndex = device.AcquireNextImageKHR(swapchain, ulong.MaxValue, semaphore);
            UInt32 nextIndex;

            vkAPI.vkAcquireNextImageKHR(device, swapchain, ulong.MaxValue,
                                        semaphore, new VkFence(), &nextIndex).Check();
            //device.ResetFence(fence);
            vkAPI.vkResetFences(device, 1, &fence).Check();

            //queue.Submit(ref this.submitInfos[nextIndex], fence);
            //VkSubmitInfo submitInfo = this.submitInfos[nextIndex];
            //vkAPI.vkQueueSubmit(queue, 1, &submitInfo, fence).Check();
            vkAPI.vkQueueSubmit(queue, 1, &this.submitInfos[nextIndex], fence).Check();
            //device.WaitForFence(fence, true, 100000000);
            vkAPI.vkWaitForFences(device, 1, &fence, true, 100000000).Check();
            //queue.PresentKHR(ref this.presentInfos[nextIndex]);
            //VkPresentInfoKHR presentInfo = this.presentInfos[nextIndex];
            //vkAPI.vkQueuePresentKHR(queue, &presentInfo).Check();
            vkAPI.vkQueuePresentKHR(queue, &this.presentInfos[nextIndex]).Check();
        }
예제 #5
0
        /// <summary>
        /// Submit an executable command buffer with optional wait and signal semaphores, and an optional fence to be signaled when the commands have been completed.
        /// </summary>
        /// <param name="queue">Queue.</param>
        /// <param name="wait">Wait.</param>
        /// <param name="signal">Signal.</param>
        /// <param name="fence">Fence.</param>
        public void Submit(VkQueue queue, VkSemaphore wait = default, VkSemaphore signal = default, Fence fence = null)
        {
            VkSubmitInfo submit_info = VkSubmitInfo.New();

            IntPtr dstStageMask = Marshal.AllocHGlobal(sizeof(uint));

            Marshal.WriteInt32(dstStageMask, (int)VkPipelineStageFlags.ColorAttachmentOutput);

            using (PinnedObjects pctx = new PinnedObjects()) {
                submit_info.pWaitDstStageMask = dstStageMask;
                if (signal != VkSemaphore.Null)
                {
                    submit_info.signalSemaphoreCount = 1;
                    submit_info.pSignalSemaphores    = signal.Pin(pctx);
                }
                if (wait != VkSemaphore.Null)
                {
                    submit_info.waitSemaphoreCount = 1;
                    submit_info.pWaitSemaphores    = wait.Pin(pctx);
                }

                submit_info.commandBufferCount = 1;
                submit_info.pCommandBuffers    = handle.Pin(pctx);

                Utils.CheckResult(vkQueueSubmit(queue, 1, ref submit_info, fence));
            }
            Marshal.FreeHGlobal(dstStageMask);
        }
예제 #6
0
파일: VulkanDevice.cs 프로젝트: gomson/vk
        /**
         * Finish command buffer recording and submit it to a queue
         *
         * @param commandBuffer Command buffer to flush
         * @param queue Queue to submit the command buffer to
         * @param free (Optional) Free the command buffer once it has been submitted (Defaults to true)
         *
         * @note The queue that the command buffer is submitted to must be from the same family index as the pool it was allocated from
         * @note Uses a fence to ensure command buffer has finished executing
         */
        public void flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, bool free = true)
        {
            if (commandBuffer.Handle == NullHandle)
            {
                return;
            }

            Util.CheckResult(vkEndCommandBuffer(commandBuffer));

            VkSubmitInfo submitInfo = VkSubmitInfo.New();

            submitInfo.commandBufferCount = 1;
            submitInfo.pCommandBuffers    = &commandBuffer;

            // Create fence to ensure that the command buffer has finished executing
            VkFenceCreateInfo fenceInfo = VkFenceCreateInfo.New();

            fenceInfo.flags = VkFenceCreateFlags.None;
            VkFence fence;

            Util.CheckResult(vkCreateFence(_logicalDevice, &fenceInfo, null, &fence));

            // Submit to the queue
            Util.CheckResult(vkQueueSubmit(queue, 1, &submitInfo, fence));
            // Wait for the fence to signal that command buffer has finished executing
            Util.CheckResult(vkWaitForFences(_logicalDevice, 1, &fence, True, DEFAULT_FENCE_TIMEOUT));

            vkDestroyFence(_logicalDevice, fence, null);

            if (free)
            {
                vkFreeCommandBuffers(_logicalDevice, CommandPool, 1, &commandBuffer);
            }
        }
예제 #7
0
 public static VkResult vkQueueBindSparse(VkQueue queue, ReadOnlySpan <VkBindSparseInfo> bindInfo, VkFence fence)
 {
     fixed(VkBindSparseInfo *bindInfoPtr = bindInfo)
     {
         return(vkQueueBindSparse(queue, bindInfo.Length, bindInfoPtr, fence));
     }
 }
예제 #8
0
 public static VkResult vkQueueSubmit(VkQueue queue, ReadOnlySpan <VkSubmitInfo> submits, VkFence fence)
 {
     fixed(VkSubmitInfo *submitsPtr = submits)
     {
         return(vkQueueSubmit(queue, submits.Length, submitsPtr, fence));
     }
 }
예제 #9
0
 internal Queue(Device device, VkQueue queue, uint familyIndex)
 {
     this.device = device;
     this.queue  = queue;
     FamilyIndex = familyIndex;
     Family      = device.PhysicalDevice.QueueFamilies[(int)familyIndex];
 }
예제 #10
0
        private void CreateLogicalDevice()
        {
            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

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

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

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

            VkPhysicalDeviceFeatures deviceFeatures = new VkPhysicalDeviceFeatures();

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

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

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

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

            VkQueue newGraphicsQueue;

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

            VkQueue newPresentQueue;

            VulkanNative.vkGetDeviceQueue(vkDevice, (uint)indices.PresentFamily, 0, &newPresentQueue);
            this.vkPresentQueue = newPresentQueue;
        }
예제 #11
0
        public void Submit(CommandBuffer[] buffers, VkSemaphore[] wait, VkPipelineStageFlag[] waitStages,
                           VkSemaphore[] signal, VkFence submit)
        {
            unsafe
            {
                // ReSharper disable once PossibleNullReferenceException
                Debug.Assert((waitStages == null && wait == null) || waitStages.Length == wait.Length);
                var arrayBuffers = buffers.Where(x => !(x is CommandBufferPooledExclusiveUse)).Select(x =>
                {
                    x.AssertBuilt();
                    return(x.Handle);
                }).ToArray();
                var pooledBuffers = buffers.OfType <CommandBufferPooledExclusiveUse>().ToArray();
                Debug.Assert(pooledBuffers.Length == 0 || submit == VkFence.Null,
                             "Can't use custom submit fence on pooled buffers");
                fixed(VkSemaphore *waitPtr = wait)
                fixed(VkPipelineStageFlag * waitStagePtr = waitStages)
                fixed(VkSemaphore * signalPtr            = signal)
                {
                    if (arrayBuffers.Length > 0)
                        fixed(VkCommandBuffer *buffer = arrayBuffers)
                        {
                            var info = new VkSubmitInfo()
                            {
                                SType = VkStructureType.SubmitInfo,
                                PNext = IntPtr.Zero,
                                CommandBufferCount   = (uint)arrayBuffers.Length,
                                PCommandBuffers      = buffer,
                                SignalSemaphoreCount = (uint)(signal?.Length ?? 0),
                                PSignalSemaphores    = signalPtr,
                                WaitSemaphoreCount   = (uint)(wait?.Length ?? 0),
                                PWaitSemaphores      = waitPtr,
                                PWaitDstStageMask    = waitStagePtr,
                            };

                            VkException.Check(VkQueue.vkQueueSubmit(Handle, 1, &info, submit));
                        }
                    foreach (var pooled in pooledBuffers)
                    {
                        var handle = pooled.Handle;
                        var info   = new VkSubmitInfo()
                        {
                            SType = VkStructureType.SubmitInfo,
                            PNext = IntPtr.Zero,
                            CommandBufferCount   = 1,
                            PCommandBuffers      = &handle,
                            SignalSemaphoreCount = (uint)(signal?.Length ?? 0),
                            PSignalSemaphores    = signalPtr,
                            WaitSemaphoreCount   = (uint)(wait?.Length ?? 0),
                            PWaitSemaphores      = waitPtr,
                            PWaitDstStageMask    = waitStagePtr,
                        };
                        pooled.DoSubmit(Handle, info);
                    }
                }
            }
        }
예제 #12
0
        public static VkResult vkQueueSubmit(VkQueue queue, int submitCount, VkSubmitInfo[] pSubmits, VkFence fence)
        {
            VkPreconditions.CheckNull(queue, nameof(queue));
            VkPreconditions.CheckNull(pSubmits, nameof(pSubmits));

            VkPreconditions.CheckRange(submitCount, 1, int.MaxValue, nameof(submitCount));
            VkPreconditions.CheckRange(pSubmits.Length < submitCount, nameof(pSubmits.Length));

            return(GetQueue(queue).Submit(submitCount, pSubmits, fence));
        }
예제 #13
0
        /**
         * Queue an image for presentation
         *
         * @param queue Presentation queue for presenting the image
         * @param imageIndex Index of the swapchain image to queue for presentation
         * @param waitSemaphore (Optional) Semaphore that is waited on before the image is presented (only used if != VK_NULL_HANDLE)
         *
         * @return VkResult of the queue presentation
         */
        public VkResult QueuePresent(VkQueue queue, uint imageIndex, VkSemaphore waitSemaphore = new VkSemaphore())
        {
            var presentInfo = VkPresentInfoKHR.Alloc();

            presentInfo->swapchainsImages.Set(Swapchain);
            presentInfo->swapchainsImages.Set(imageIndex);
            // Check if a wait semaphore has been specified to wait for before presenting the image
            if (waitSemaphore != 0ul)
            {
                presentInfo->waitSemaphores = waitSemaphore;
            }
            return(vkQueuePresentKHR(queue, presentInfo));
        }
예제 #14
0
 internal unsafe void SubmitCommand(
     VkQueue queue,
     List <Semaphore> signalSemaphores,
     List <Semaphore> waitSemaphores,
     VkPipelineStageFlags waitStageMask = VkPipelineStageFlags.TopOfPipe
     ) => SubmitCommands(
     new List <CommandBuffer> {
     this
 },
     queue,
     signalSemaphores,
     waitSemaphores,
     waitStageMask
     );
예제 #15
0
        /**
         * Queue an image for presentation
         *
         * @param queue Presentation queue for presenting the image
         * @param imageIndex Index of the swapchain image to queue for presentation
         * @param waitSemaphore (Optional) Semaphore that is waited on before the image is presented (only used if != VK_NULL_HANDLE)
         *
         * @return VkResult of the queue presentation
         */
        public VkResult QueuePresent(VkQueue queue, uint imageIndex, VkSemaphore waitSemaphore = new VkSemaphore())
        {
            VkPresentInfoKHR presentInfo = VkPresentInfoKHR.New();

            presentInfo.pNext          = null;
            presentInfo.swapchainCount = 1;
            var sc = Swapchain;

            presentInfo.pSwapchains   = &sc;
            presentInfo.pImageIndices = &imageIndex;
            // Check if a wait semaphore has been specified to wait for before presenting the image
            if (waitSemaphore.Handle != 0)
            {
                presentInfo.pWaitSemaphores    = &waitSemaphore;
                presentInfo.waitSemaphoreCount = 1;
            }
            return(vkQueuePresentKHR(queue, &presentInfo));
        }
예제 #16
0
파일: VkModule.cs 프로젝트: riiji/VkQueue
        public void DeleteMessageInConversation(long conversationId, long messageId, bool clear)
        {
            try
            {
                VkApi.Messages.Delete(new[] { (ulong)messageId }, null, null, true);

                if (clear)
                {
                    VkQueue = new VkQueue();
                }

                Log.Message("VkModule", $"Message {messageId} deleted");
            }
            catch (Exception e)
            {
                throw new VkBotException($"Can't delete message in conversation. Error : {e.Message}");
            }
        }
예제 #17
0
        public override void Init()
        {
            queue = Graphics.WorkQueue;

            scene = new Scene()
            {
                new Octree {
                },
                new DebugRenderer {
                },

                new Environment
                {
                    SunlightDir = glm.normalize(new vec3(-1.0f, -1.0f, 0.0f))
                },

                new Node("Camera", new vec3(0, 2, -10), glm.radians(10, 0, 0))
                {
                    new Camera
                    {
                        NearClip = 0.5f,
                        FarClip  = 400,
                    },
                },
            };

            camera = scene.GetComponent <Camera>(true);

            PrepareSparseTexture(4096, 4096, 1, VkFormat.R8G8B8A8UNorm);

            {
                var node        = scene.CreateChild("Plane");
                var staticModel = node.AddComponent <StaticModel>();
                var model       = GeometryUtil.CreatePlaneModel(100, 100, 1, 1);
                staticModel.SetModel(model);

                var mat = new Material("shaders/VirtualTexture.shader");
                mat.SetTexture("samplerColor", texture);
                staticModel.SetMaterial(mat);
            }

            MainView.Attach(camera, scene);
        }
예제 #18
0
        private void CreateTexture(VkDevice device, VkPhysicalDevice physicalDevice, VkQueue graphicsQueue)
        {
            SimpleTgaReader tex     = new SimpleTgaReader("resource/texture.tga");
            var             command = m_commandBuffers[1];

            SampleHelpers.CreateTexture(device, physicalDevice,
                                        tex.Width, tex.Height, tex.ImageData,
                                        out m_image, out m_imageMemory, graphicsQueue, command);

            // イメージビューの作成.
            var imageViewCreateInfo = new VkImageViewCreateInfo()
            {
                image            = m_image,
                viewType         = VkImageViewType.VK_IMAGE_VIEW_TYPE_2D,
                format           = VkFormat.VK_FORMAT_B8G8R8A8_UNORM,
                components       = new VkComponentMapping(),
                subresourceRange = new VkImageSubresourceRange()
                {
                    aspectMask     = VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT,
                    baseArrayLayer = 0,
                    baseMipLevel   = 0,
                    levelCount     = 1,
                    layerCount     = 1,
                }
            };

            VulkanAPI.vkCreateImageView(device, ref imageViewCreateInfo, out m_imageView);

            // サンプラーの作成.
            var samplerCreateInfo = new VkSamplerCreateInfo()
            {
                magFilter    = VkFilter.VK_FILTER_LINEAR,
                minFilter    = VkFilter.VK_FILTER_LINEAR,
                mipmapMode   = VkSamplerMipmapMode.VK_SAMPLER_MIPMAP_MODE_NEAREST,
                addressModeU = VkSamplerAddressMode.VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
                addressModeV = VkSamplerAddressMode.VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
            };

            VulkanAPI.vkCreateSampler(device, ref samplerCreateInfo, out m_imageSampler);
        }
예제 #19
0
        protected void flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, bool free)
        {
            if (commandBuffer.handle == 0)
            {
                return;
            }

            vkEndCommandBuffer(commandBuffer);

            VkSubmitInfo submitInfo = new VkSubmitInfo();

            submitInfo.sType          = SubmitInfo;
            submitInfo.commandBuffers = commandBuffer;

            vkQueueSubmit(queue, 1, &submitInfo, new VkFence());
            vkQueueWaitIdle(queue);

            if (free)
            {
                vkFreeCommandBuffers(device, cmdPool, 1, &commandBuffer);
            }
        }
예제 #20
0
        protected void flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, bool free)
        {
            if (commandBuffer == NullHandle)
            {
                return;
            }

            Util.CheckResult(vkEndCommandBuffer(commandBuffer));

            VkSubmitInfo submitInfo = VkSubmitInfo.New();

            submitInfo.commandBufferCount = 1;
            submitInfo.pCommandBuffers    = &commandBuffer;

            Util.CheckResult(vkQueueSubmit(queue, 1, &submitInfo, VkFence.Null));
            Util.CheckResult(vkQueueWaitIdle(queue));

            if (free)
            {
                vkFreeCommandBuffers(device, cmdPool, 1, &commandBuffer);
            }
        }
예제 #21
0
        public static VkResult vkQueuePresentKHR(VkQueue queue, VkSemaphore waitSemaphore, VkSwapchainKHR swapchain, uint imageIndex)
        {
            var presentInfo = new VkPresentInfoKHR
            {
                sType = VkStructureType.PresentInfoKHR,
                pNext = null
            };

            if (waitSemaphore != VkSemaphore.Null)
            {
                presentInfo.waitSemaphoreCount = 1u;
                presentInfo.pWaitSemaphores    = &waitSemaphore;
            }

            if (swapchain != VkSwapchainKHR.Null)
            {
                presentInfo.swapchainCount = 1u;
                presentInfo.pSwapchains    = &swapchain;
                presentInfo.pImageIndices  = &imageIndex;
            }

            return(vkQueuePresentKHR(queue, &presentInfo));
        }
예제 #22
0
        void CreateDevice()
        {
            var features = physicalDevice.Features;

            var uniqueIndices = new HashSet <int> {
                graphicsIndex, presentIndex
            };
            var priorities = new List <float> {
                1f
            };
            var queueInfos = new List <VkDeviceQueueCreateInfo>(uniqueIndices.Count);

            int i = 0;

            foreach (var ind in uniqueIndices)
            {
                var queueInfo = new VkDeviceQueueCreateInfo {
                    queueFamilyIndex = ind,
                    queueCount       = 1,
                    priorities       = priorities
                };

                queueInfos.Add(queueInfo);
                i++;
            }

            var info = new VkDeviceCreateInfo {
                extensions       = deviceExtensions,
                queueCreateInfos = queueInfos,
                features         = features
            };

            device = new VkDevice(physicalDevice, info);

            graphicsQueue = device.GetQueue(graphicsIndex, 0);
            presentQueue  = device.GetQueue(presentIndex, 0);
        }
예제 #23
0
 public static extern VkResult QueueBindSparse(
     VkQueue queue,
     uint bindInfoCount,
     ref VkBindSparseInfo pBindInfo,
     VkFence fence
     );
예제 #24
0
        public void Init(IntPtr hwnd, IntPtr processHandle)
        {
            if (this.isInitialized)
            {
                return;
            }

            this.instance = InitInstance();
            InitDebugCallback(this.instance);
            this.surface          = InitSurface(this.instance, hwnd, processHandle);
            this.vkPhysicalDevice = InitPhysicalDevice(this.instance);
            VkSurfaceFormatKHR surfaceFormat = SelectFormat(this.vkPhysicalDevice, this.surface);

            this.device = CreateDevice(this.vkPhysicalDevice, this.surface);

            this.vkQueue = this.device.GetQueue(0, 0);

            VkSurfaceCapabilitiesKHR surfaceCapabilities;

            //this.vkPhysicalDevice.GetSurfaceCapabilitiesKhr(this.vkSurface, out surfaceCapabilities);
            vkAPI.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(this.vkPhysicalDevice, this.surface, &surfaceCapabilities).Check();

            this.swapchain = CreateSwapchain(this.device, this.surface, surfaceFormat, surfaceCapabilities);

            this.vkImages = this.device.GetSwapchainImages(this.swapchain);

            this.renderPass = CreateRenderPass(this.device, surfaceFormat);

            this.framebuffers = CreateFramebuffers(this.device, this.vkImages, surfaceFormat, this.renderPass, surfaceCapabilities);

            this.vkFence     = this.device.CreateFence();
            this.vkSemaphore = this.device.CreateSemaphore();

            // buffers for vertex data.
            VkBuffer vertexBuffer = CreateBuffer(this.vkPhysicalDevice, this.device, Vertices, VkBufferUsageFlagBits.VertexBuffer, typeof(float));

            VkBuffer indexBuffer = CreateBuffer(this.vkPhysicalDevice, this.device, Indexes, VkBufferUsageFlagBits.IndexBuffer, typeof(short));

            var uniformBufferData = new AreaUniformBuffer(1, 1);

            this.originalWidth  = 1; this.width = this.originalWidth;
            this.originalHeight = 1; this.height = this.originalHeight;

            this.uniformBuffer = CreateBuffer(this.vkPhysicalDevice, this.device, uniformBufferData, VkBufferUsageFlagBits.UniformBuffer, typeof(AreaUniformBuffer));

            this.descriptorSetLayout = CreateDescriptorSetLayout(this.device);

            this.vkPipelineLayout = CreatePipelineLayout(this.device, this.descriptorSetLayout);

            VkPipeline pipeline = CreatePipeline(this.device, surfaceCapabilities, this.renderPass, this.vkPipelineLayout);

            this.descriptorSet = CreateDescriptorSet(this.device, this.descriptorSetLayout);

            UpdateDescriptorSets(this.device, this.uniformBuffer, this.descriptorSet);

            this.commandBuffers = CreateCommandBuffers(
                this.device, this.renderPass, surfaceCapabilities,
                this.vkImages, this.framebuffers, pipeline,
                vertexBuffer, indexBuffer, (uint)Indexes.Length,
                this.vkPipelineLayout, this.descriptorSet);

            this.isInitialized = true;
        }
예제 #25
0
        /**
         * Load a 2D texture including all mip levels
         *
         * @param filename File to load (supports .ktx and .dds)
         * @param format Vulkan format of the image data stored in the file
         * @param device Vulkan device to create the texture on
         * @param copyQueue Queue used for the texture staging copy commands (must support transfer)
         * @param (Optional) imageUsageFlags Usage flags for the texture's image (defaults to VK_IMAGE_USAGE_SAMPLED_BIT)
         * @param (Optional) imageLayout Usage layout for the texture (defaults VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
         * @param (Optional) forceLinear Force linear tiling (not advised, defaults to false)
         *
         */
        public void loadFromFile(
            string filename,
            VkFormat format,
            vksVulkanDevice device,
            VkQueue copyQueue,
            VkImageUsageFlagBits imageUsageFlags = VkImageUsageFlagBits.Sampled,
            VkImageLayout imageLayout            = VkImageLayout.ShaderReadOnlyOptimal,
            bool forceLinear = false)
        {
            KtxFile tex2D;

            using (var fs = File.OpenRead(filename)) {
                tex2D = KtxFile.Load(fs, false);
            }

            this.device = device;
            width       = tex2D.Header.PixelWidth;
            height      = tex2D.Header.PixelHeight;
            if (height == 0)
            {
                height = width;
            }
            mipLevels = tex2D.Header.NumberOfMipmapLevels;

            // Get device properites for the requested texture format
            VkFormatProperties formatProperties;

            vkGetPhysicalDeviceFormatProperties(device.PhysicalDevice, format, &formatProperties);

            // Only use linear tiling if requested (and supported by the device)
            // Support for linear tiling is mostly limited, so prefer to use
            // optimal tiling instead
            // On most implementations linear tiling will only support a very
            // limited amount of formats and features (mip maps, cubemaps, arrays, etc.)
            bool useStaging = !forceLinear;

            VkMemoryAllocateInfo memAllocInfo = new VkMemoryAllocateInfo();

            memAllocInfo.sType = MemoryAllocateInfo;
            VkMemoryRequirements memReqs;

            // Use a separate command buffer for texture loading
            VkCommandBuffer copyCmd = device.createCommandBuffer(VkCommandBufferLevel.Primary, true);

            if (useStaging)
            {
                // Create a host-visible staging buffer that contains the raw image data
                VkBuffer       stagingBuffer;
                VkDeviceMemory stagingMemory;

                VkBufferCreateInfo bufferCreateInfo = new VkBufferCreateInfo();
                bufferCreateInfo.sType = BufferCreateInfo;
                bufferCreateInfo.size  = tex2D.GetTotalSize();
                // This buffer is used as a transfer source for the buffer copy
                bufferCreateInfo.usage       = VkBufferUsageFlagBits.TransferSrc;
                bufferCreateInfo.sharingMode = VkSharingMode.Exclusive;

                vkCreateBuffer(device.LogicalDevice, &bufferCreateInfo, null, &stagingBuffer);

                // Get memory requirements for the staging buffer (alignment, memory type bits)
                vkGetBufferMemoryRequirements(device.LogicalDevice, stagingBuffer, &memReqs);

                memAllocInfo.allocationSize = memReqs.size;
                // Get memory type index for a host visible buffer
                memAllocInfo.memoryTypeIndex = device.getMemoryType(memReqs.memoryTypeBits,
                                                                    VkMemoryPropertyFlagBits.HostVisible | VkMemoryPropertyFlagBits.HostCoherent);

                vkAllocateMemory(device.LogicalDevice, &memAllocInfo, null, &stagingMemory);
                vkBindBufferMemory(device.LogicalDevice, stagingBuffer, stagingMemory, 0);

                // Copy texture data into staging buffer
                IntPtr data;
                vkMapMemory(device.LogicalDevice, stagingMemory, 0, memReqs.size, 0, &data);
                byte[] pixelData = tex2D.GetAllTextureData();
                fixed(byte *pixelDataPtr = &pixelData[0])
                {
                    Unsafe.CopyBlock(data, pixelDataPtr, (uint)pixelData.Length);
                }

                vkUnmapMemory(device.LogicalDevice, stagingMemory);

                // Setup buffer copy regions for each mip level
                var  bufferCopyRegions = new List <VkBufferImageCopy>();
                uint offset            = 0;

                for (uint i = 0; i < mipLevels; i++)
                {
                    VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy();
                    bufferCopyRegion.imageSubresource.aspectMask     = VkImageAspectFlagBits.Color;
                    bufferCopyRegion.imageSubresource.mipLevel       = i;
                    bufferCopyRegion.imageSubresource.baseArrayLayer = 0;
                    bufferCopyRegion.imageSubresource.layerCount     = 1;
                    bufferCopyRegion.imageExtent.width  = tex2D.Faces[0].Mipmaps[i].Width;
                    bufferCopyRegion.imageExtent.height = tex2D.Faces[0].Mipmaps[i].Height;
                    bufferCopyRegion.imageExtent.depth  = 1;
                    bufferCopyRegion.bufferOffset       = offset;

                    bufferCopyRegions.Add(bufferCopyRegion);

                    offset += tex2D.Faces[0].Mipmaps[i].SizeInBytes;
                }

                // Create optimal tiled target image
                VkImageCreateInfo imageCreateInfo = new VkImageCreateInfo();
                imageCreateInfo.sType         = ImageCreateInfo;
                imageCreateInfo.imageType     = VkImageType._2d;
                imageCreateInfo.format        = format;
                imageCreateInfo.mipLevels     = mipLevels;
                imageCreateInfo.arrayLayers   = 1;
                imageCreateInfo.samples       = VkSampleCountFlagBits._1;
                imageCreateInfo.tiling        = VkImageTiling.Optimal;
                imageCreateInfo.sharingMode   = VkSharingMode.Exclusive;
                imageCreateInfo.initialLayout = VkImageLayout.Undefined;
                imageCreateInfo.extent        = new VkExtent3D {
                    width = width, height = height, depth = 1
                };
                imageCreateInfo.usage = imageUsageFlags;
                // Ensure that the TRANSFER_DST bit is set for staging
                if ((imageCreateInfo.usage & VkImageUsageFlagBits.TransferDst) == 0)
                {
                    imageCreateInfo.usage |= VkImageUsageFlagBits.TransferDst;
                }
                {
                    VkImage vkImage;
                    vkCreateImage(device.LogicalDevice, &imageCreateInfo, null, &vkImage);
                    this.image = vkImage;
                }

                vkGetImageMemoryRequirements(device.LogicalDevice, image, &memReqs);

                memAllocInfo.allocationSize = memReqs.size;

                memAllocInfo.memoryTypeIndex = device.getMemoryType(memReqs.memoryTypeBits,
                                                                    VkMemoryPropertyFlagBits.DeviceLocal);
                {
                    VkDeviceMemory memory;
                    vkAllocateMemory(device.LogicalDevice, &memAllocInfo, null, &memory);
                    this.deviceMemory = memory;
                }
                vkBindImageMemory(device.LogicalDevice, image, deviceMemory, 0);

                VkImageSubresourceRange subresourceRange = new VkImageSubresourceRange();
                subresourceRange.aspectMask   = VkImageAspectFlagBits.Color;
                subresourceRange.baseMipLevel = 0;
                subresourceRange.levelCount   = mipLevels;
                subresourceRange.layerCount   = 1;

                // Image barrier for optimal image (target)
                // Optimal image will be used as destination for the copy
                Tools.setImageLayout(
                    copyCmd,
                    image,
                    VkImageAspectFlagBits.Color,
                    VkImageLayout.Undefined,
                    VkImageLayout.TransferDstOptimal,
                    subresourceRange);

                // Copy mip levels from staging buffer
                fixed(VkBufferImageCopy *pointer = bufferCopyRegions.ToArray())
                {
                    vkCmdCopyBufferToImage(
                        copyCmd,
                        stagingBuffer,
                        image,
                        VkImageLayout.TransferDstOptimal,
                        (UInt32)bufferCopyRegions.Count,
                        pointer);
                }

                // Change texture image layout to shader read after all mip levels have been copied
                this.imageLayout = imageLayout;
                Tools.setImageLayout(
                    copyCmd,
                    image,
                    VkImageAspectFlagBits.Color,
                    VkImageLayout.TransferDstOptimal,
                    imageLayout,
                    subresourceRange);

                device.flushCommandBuffer(copyCmd, copyQueue);

                // Clean up staging resources
                vkFreeMemory(device.LogicalDevice, stagingMemory, null);
                vkDestroyBuffer(device.LogicalDevice, stagingBuffer, null);
            }
            else
            {
                throw new NotImplementedException();

                /*
                 * // Prefer using optimal tiling, as linear tiling
                 * // may support only a small set of features
                 * // depending on implementation (e.g. no mip maps, only one layer, etc.)
                 *
                 * // Check if this support is supported for linear tiling
                 * Debug.Assert((formatProperties.linearTilingFeatures & VkFormatFeatureFlags.SampledImage) != 0);
                 *
                 * VkImage mappableImage;
                 * VkDeviceMemory mappableMemory;
                 *
                 * VkImageCreateInfo imageCreateInfo = Initializers.imageCreateInfo();
                 * imageCreateInfo.imageType = VkImageType._2d;
                 * imageCreateInfo.format = format;
                 * imageCreateInfo.extent = new VkExtent3D { width = width, height = height, depth = 1 };
                 * imageCreateInfo.mipLevels = 1;
                 * imageCreateInfo.arrayLayers = 1;
                 * imageCreateInfo.samples = VkSampleCountFlags._1;
                 * imageCreateInfo.tiling = VkImageTiling.Linear;
                 * imageCreateInfo.usage = imageUsageFlags;
                 * imageCreateInfo.sharingMode = VkSharingMode.Exclusive;
                 * imageCreateInfo.initialLayout = VkImageLayout.Undefined;
                 *
                 * // Load mip map level 0 to linear tiling image
                 * Util.CheckResult(vkCreateImage(device.LogicalDevice, &imageCreateInfo, null, &mappableImage));
                 *
                 * // Get memory requirements for this image
                 * // like size and alignment
                 * vkGetImageMemoryRequirements(device.LogicalDevice, mappableImage, &memReqs);
                 * // Set memory allocation size to required memory size
                 * memAllocInfo.allocationSize = memReqs.size;
                 *
                 * // Get memory type that can be mapped to host memory
                 * memAllocInfo.memoryTypeIndex = device.GetMemoryType(memReqs.memoryTypeBits, VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent);
                 *
                 * // Allocate host memory
                 * Util.CheckResult(vkAllocateMemory(device.LogicalDevice, &memAllocInfo, null, &mappableMemory));
                 *
                 * // Bind allocated image for use
                 * Util.CheckResult(vkBindImageMemory(device.LogicalDevice, mappableImage, mappableMemory, 0));
                 *
                 * // Get sub resource layout
                 * // Mip map count, array layer, etc.
                 * VkImageSubresource subRes = new VkImageSubresource();
                 * subRes.aspectMask = VkImageAspectFlags.Color;
                 * subRes.mipLevel = 0;
                 *
                 * VkSubresourceLayout subResLayout;
                 * void* data;
                 *
                 * // Get sub resources layout
                 * // Includes row pitch, size offsets, etc.
                 * vkGetImageSubresourceLayout(device.LogicalDevice, mappableImage, &subRes, &subResLayout);
                 *
                 * // Map image memory
                 * Util.CheckResult(vkMapMemory(device.LogicalDevice, mappableMemory, 0, memReqs.size, 0, &data));
                 *
                 * // Copy image data into memory
                 * memcpy(data, tex2D[subRes.mipLevel].data(), tex2D[subRes.mipLevel].size());
                 *
                 * vkUnmapMemory(device.LogicalDevice, mappableMemory);
                 *
                 * // Linear tiled images don't need to be staged
                 * // and can be directly used as textures
                 * image = mappableImage;
                 * deviceMemory = mappableMemory;
                 * imageLayout = imageLayout;
                 *
                 * // Setup image memory barrier
                 * vks::tools::setImageLayout(copyCmd, image, VkImageAspectFlags.Color, VkImageLayout.Undefined, imageLayout);
                 *
                 * device.flushCommandBuffer(copyCmd, copyQueue);
                 */
            }

            // Create a defaultsampler
            VkSamplerCreateInfo samplerCreateInfo = new VkSamplerCreateInfo();

            samplerCreateInfo.sType        = SamplerCreateInfo;
            samplerCreateInfo.magFilter    = VkFilter.Linear;
            samplerCreateInfo.minFilter    = VkFilter.Linear;
            samplerCreateInfo.mipmapMode   = VkSamplerMipmapMode.Linear;
            samplerCreateInfo.addressModeU = VkSamplerAddressMode.Repeat;
            samplerCreateInfo.addressModeV = VkSamplerAddressMode.Repeat;
            samplerCreateInfo.addressModeW = VkSamplerAddressMode.Repeat;
            samplerCreateInfo.mipLodBias   = 0.0f;
            samplerCreateInfo.compareOp    = VkCompareOp.Never;
            samplerCreateInfo.minLod       = 0.0f;
            // Max level-of-detail should match mip level count
            samplerCreateInfo.maxLod = (useStaging) ? (float)mipLevels : 0.0f;
            // Enable anisotropic filtering
            samplerCreateInfo.maxAnisotropy    = 8;
            samplerCreateInfo.anisotropyEnable = true;
            samplerCreateInfo.borderColor      = VkBorderColor.FloatOpaqueWhite;
            {
                VkSampler vkSampler;
                vkCreateSampler(device.LogicalDevice, &samplerCreateInfo, null, &vkSampler);
                this.sampler = vkSampler;
            }

            // Create image view
            // Textures are not directly accessed by the shaders and
            // are abstracted by image views containing additional
            // information and sub resource ranges
            VkImageViewCreateInfo viewCreateInfo = new VkImageViewCreateInfo();

            viewCreateInfo.sType      = ImageViewCreateInfo;
            viewCreateInfo.viewType   = VkImageViewType._2d;
            viewCreateInfo.format     = format;
            viewCreateInfo.components = new VkComponentMapping {
                r = VkComponentSwizzle.R,
                g = VkComponentSwizzle.G,
                b = VkComponentSwizzle.B,
                a = VkComponentSwizzle.A
            };
            viewCreateInfo.subresourceRange = new VkImageSubresourceRange {
                aspectMask   = VkImageAspectFlagBits.Color,
                baseMipLevel = 0, levelCount = 1, baseArrayLayer = 0, layerCount = 1
            };
            // Linear tiling usually won't support mip maps
            // Only set mip map count if optimal tiling is used
            viewCreateInfo.subresourceRange.levelCount = (useStaging) ? mipLevels : 1;
            viewCreateInfo.image = image;
            {
                VkImageView vkImageView;
                vkCreateImageView(device.LogicalDevice, &viewCreateInfo, null, &vkImageView);
                this.view = vkImageView;
            }

            // Update descriptor image info member that can be used for setting up descriptor sets
            updateDescriptor();
        }
예제 #26
0
 private static IVkQueue GetQueue(VkQueue queue)
 {
     return((IVkQueue)queue);
 }
예제 #27
0
        public static VkResult vkQueueWaitIdle(VkQueue queue)
        {
            VkPreconditions.CheckNull(queue, nameof(queue));

            return(GetQueue(queue).WaitIdle());
        }
예제 #28
0
        public static VkResult vkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR pPresentInfo)
        {
            VkPreconditions.CheckNull(queue, nameof(queue));

            return(GetQueue(queue).Present(pPresentInfo));
        }
예제 #29
0
 public static extern VkResult QueueWaitIdle(
     VkQueue queue
     );
예제 #30
0
        public static void vkGetDeviceQueue(VkDevice device, int queueFamilyIndex, int queueIndex, out VkQueue pQueue)
        {
            VkPreconditions.CheckNull(device, nameof(device));
            VkPreconditions.CheckRange(queueFamilyIndex, 0, int.MaxValue, nameof(queueFamilyIndex));
            VkPreconditions.CheckRange(queueIndex, 0, int.MaxValue, nameof(queueIndex));

            GetDevice(device).GetQueue(queueFamilyIndex, queueIndex, out pQueue);
        }