public void FlushCommandBuffer(CommandBuffer cmd) { if (cmd.vkCmd == NullHandle) { return; } if (!cmd.ended) { cmd.End(); } var vkCmd = cmd.vkCmd; VkSubmitInfo submitInfo = VkSubmitInfo.New(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &vkCmd; VkFenceCreateInfo fenceInfo = VkFenceCreateInfo.New(); Util.CheckResult(vkCreateFence(device, &fenceInfo, null, out VkFence fence)); Util.CheckResult(vkQueueSubmit(queue, 1, &submitInfo, fence)); //Wait for CommandBuffer to finish Util.CheckResult(vkWaitForFences(device, 1, ref fence, true, 10000000000)); vkDestroyFence(device, fence, null); }
private void CreateFences() { VkFenceCreateInfo fenceCI = VkFenceCreateInfo.New(); fenceCI.flags = VkFenceCreateFlags.None; vkCreateFence(_device, ref fenceCI, null, out _imageAvailableFence); }
/** * 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); } }
public VkFence CreateFence(bool signaled = false) { VkFence tmp; VkFenceCreateInfo info = VkFenceCreateInfo.New(); info.flags = signaled ? VkFenceCreateFlags.Signaled : 0; Utils.CheckResult(vkCreateFence(dev, ref info, IntPtr.Zero, out tmp)); return(tmp); }
public VkFence(VkGraphicsDevice gd, bool signaled) { _gd = gd; VkFenceCreateInfo fenceCI = VkFenceCreateInfo.New(); fenceCI.flags = signaled ? VkFenceCreateFlags.Signaled : VkFenceCreateFlags.None; VkResult result = vkCreateFence(_gd.Device, ref fenceCI, null, out _fence); VulkanUtil.CheckResult(result); }
private void CopyDataSingleStagingBuffer(IntPtr pixelsFront, IntPtr pixelsBack, IntPtr pixelsLeft, IntPtr pixelsRight, IntPtr pixelsTop, IntPtr pixelsBottom, VkMemoryRequirements memReqs) { VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New(); bufferCI.size = memReqs.size; bufferCI.usage = VkBufferUsageFlags.TransferSrc; vkCreateBuffer(_device, ref bufferCI, null, out VkBuffer stagingBuffer); vkGetBufferMemoryRequirements(_device, stagingBuffer, out VkMemoryRequirements stagingMemReqs); VkMemoryBlock stagingMemory = _memoryManager.Allocate( FindMemoryType( _physicalDevice, stagingMemReqs.memoryTypeBits, VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent), stagingMemReqs.size, stagingMemReqs.alignment); VkResult result = vkBindBufferMemory(_device, stagingBuffer, stagingMemory.DeviceMemory, 0); CheckResult(result); StackList <IntPtr, Size6IntPtr> faces = new StackList <IntPtr, Size6IntPtr>(); faces.Add(pixelsRight); faces.Add(pixelsLeft); faces.Add(pixelsTop); faces.Add(pixelsBottom); faces.Add(pixelsBack); faces.Add(pixelsFront); for (uint i = 0; i < 6; i++) { VkImageSubresource subresource; subresource.aspectMask = VkImageAspectFlags.Color; subresource.arrayLayer = i; subresource.mipLevel = 0; vkGetImageSubresourceLayout(_device, _image, ref subresource, out VkSubresourceLayout faceLayout); void *mappedPtr; result = vkMapMemory(_device, stagingMemory.DeviceMemory, faceLayout.offset, faceLayout.size, 0, &mappedPtr); CheckResult(result); Buffer.MemoryCopy((void *)faces[i], mappedPtr, faceLayout.size, faceLayout.size); vkUnmapMemory(_device, stagingMemory.DeviceMemory); } StackList <VkBufferImageCopy, Size512Bytes> copyRegions = new StackList <VkBufferImageCopy, Size512Bytes>(); for (uint i = 0; i < 6; i++) { VkImageSubresource subres; subres.aspectMask = VkImageAspectFlags.Color; subres.mipLevel = 0; subres.arrayLayer = i; vkGetImageSubresourceLayout(_device, _image, ref subres, out VkSubresourceLayout layout); VkBufferImageCopy copyRegion; copyRegion.bufferOffset = layout.offset; copyRegion.bufferImageHeight = 0; copyRegion.bufferRowLength = 0; copyRegion.imageExtent.width = (uint)Width; copyRegion.imageExtent.height = (uint)Height; copyRegion.imageExtent.depth = 1; copyRegion.imageOffset.x = 0; copyRegion.imageOffset.y = 0; copyRegion.imageOffset.z = 0; copyRegion.imageSubresource.baseArrayLayer = i; copyRegion.imageSubresource.aspectMask = VkImageAspectFlags.Color; copyRegion.imageSubresource.layerCount = 1; copyRegion.imageSubresource.mipLevel = 0; copyRegions.Add(copyRegion); } VkFenceCreateInfo fenceCI = VkFenceCreateInfo.New(); result = vkCreateFence(_device, ref fenceCI, null, out VkFence copyFence); CheckResult(result); TransitionImageLayout(_image, (uint)MipLevels, 0, 6, _imageLayout, VkImageLayout.TransferDstOptimal); VkCommandBuffer copyCmd = _rc.BeginOneTimeCommands(); vkCmdCopyBufferToImage(copyCmd, stagingBuffer, _image, VkImageLayout.TransferDstOptimal, copyRegions.Count, (IntPtr)copyRegions.Data); _rc.EndOneTimeCommands(copyCmd, copyFence); result = vkWaitForFences(_device, 1, ref copyFence, true, ulong.MaxValue); CheckResult(result); vkDestroyBuffer(_device, stagingBuffer, null); _memoryManager.Free(stagingMemory); }
static void Main(string[] args) { Console.WriteLine(AppContext.GetData("NATIVE_DLL_SEARCH_DIRECTORIES").ToString()); Console.WriteLine($"Hello Vulkan!"); Init(); if (!GLFW.Vulkan.IsSupported) { Console.Error.WriteLine("GLFW says that vulkan is not supported."); return; } WindowHint(Hint.ClientApi, ClientApi.None); NativeWindow window = new GLFW.NativeWindow(width, height, "Fabricor"); Glfw.SetKeyCallback(window, (a, b, c, d, e) => { GLFWInput.KeyCallback(a, b, c, d, e); }); FInstance finst = new FInstance(); VkSurfaceKHR surface = CreateSurface(finst.instance, window); VkDevice device = CreateDevice(finst.instance, out var physicalDevice, surface, out var queueFamilyIndex); VkSwapchainKHR swapchain = CreateSwapchain(VkSwapchainKHR.Null, finst.instance, device, physicalDevice, surface, queueFamilyIndex); VkRenderPass renderPass = CreateRenderPass(device); uint swapchainImageCount = 0; Assert(vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, null));////////////IMAGES VkImage[] swapchainImages = new VkImage[swapchainImageCount]; fixed(VkImage *ptr = &swapchainImages[0]) Assert(vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, ptr)); CommandPoolManager.Init(device, queueFamilyIndex); int poolId = CommandPoolManager.CreateCommandPool(VkCommandPoolCreateFlags.ResetCommandBuffer); VkSemaphoreCreateInfo pCreateInfo = VkSemaphoreCreateInfo.New(); VkSemaphore acquireSemaphore = new VkSemaphore(); vkCreateSemaphore(device, &pCreateInfo, null, &acquireSemaphore); VkSemaphore releaseSemaphore = new VkSemaphore(); vkCreateSemaphore(device, &pCreateInfo, null, &releaseSemaphore); VkQueue graphicsQueue = VkQueue.Null; vkGetDeviceQueue(device, queueFamilyIndex, 0, &graphicsQueue); string[] textures = new string[] { "res/Linus.png", "res/Alex.png", "res/Victor.png", "res/Alex2.png", //"res/Cyan.png", "res/Alex3.png", //"res/Red.png", }; FTexture texture = new FTexture(device, physicalDevice, poolId, graphicsQueue, textures, VkFormat.R8g8b8a8Unorm, 512, 512, (uint)(Math.Log(512) / Math.Log(2)) + 1); VkPipelineCache pipelineCache = VkPipelineCache.Null;//This is critcal for performance. FGraphicsPipeline voxelPipeline = new FGraphicsPipeline(device, physicalDevice, pipelineCache, renderPass, "shaders/voxel", swapchainImageCount, texture); voxelPipeline.CreateDepthBuffer(physicalDevice, (uint)width, (uint)height); VkImageView[] swapchainImageViews = new VkImageView[swapchainImageCount]; for (int i = 0; i < swapchainImageCount; i++) { swapchainImageViews[i] = FTexture.CreateColourImageView(device, swapchainImages[i], surfaceFormat.format); } VkFramebuffer[] frambuffers = new VkFramebuffer[swapchainImageCount]; for (int i = 0; i < swapchainImageCount; i++) { frambuffers[i] = CreateFramebuffer(device, renderPass, swapchainImageViews[i], voxelPipeline.depthImageView); } MeshWrapper <VoxelVertex> mesh = VoxelMeshFactory.GenerateMesh(device, physicalDevice); Action updateMesh = delegate { VoxelMeshFactory.UpdateMesh(device, physicalDevice, mesh); }; GLFWInput.Subscribe(Keys.U, updateMesh, InputState.Press); Action changeTexture = delegate { Span <VoxelVertex> span = mesh.Mesh.vertices.Map(); for (int j = 0; j < span.Length; j++) { span[j].textureId++; } span = mesh.Mesh.vertices.UnMap(); }; GLFWInput.Subscribe(Keys.F, changeTexture, InputState.Press); FCommandBuffer[] cmdBuffers = new FCommandBuffer[swapchainImageCount]; VkFence[] fences = new VkFence[swapchainImageCount]; for (int i = 0; i < swapchainImageCount; i++) { cmdBuffers[i] = new FCommandBuffer(device, poolId); VkFenceCreateInfo createInfo = VkFenceCreateInfo.New(); createInfo.flags = VkFenceCreateFlags.Signaled; VkFence fence = VkFence.Null; Assert(vkCreateFence(device, &createInfo, null, &fence)); fences[i] = fence; } FCamera camera = new FCamera(); camera.AspectWidth = width; camera.AspectHeight = height; camera.position.Z = -1f; //camera.rotation=Quaternion.CreateFromYawPitchRoll(MathF.PI,0,0); double lastTime = Glfw.Time; int nbFrames = 0; while (!WindowShouldClose(window)) { PollEvents(); GLFWInput.Update(); // Measure speed double currentTime = Glfw.Time; nbFrames++; if (currentTime - lastTime >= 1.0) { // If last prinf() was more than 1 sec ago // printf and reset timer Console.WriteLine($"ms/frame: {1000.0 / nbFrames}"); nbFrames = 0; lastTime += 1.0; } if (GLFWInput.TimeKeyPressed(Keys.D) > 0) { camera.position += Vector3.Transform(Vector3.UnitX * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.A) > 0) { camera.position -= Vector3.Transform(Vector3.UnitX * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.W) > 0) { camera.position += Vector3.Transform(Vector3.UnitZ * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.S) > 0) { camera.position -= Vector3.Transform(Vector3.UnitZ * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.Space) > 0) { camera.position += Vector3.Transform(Vector3.UnitY * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.LeftShift) > 0) { camera.position -= Vector3.Transform(Vector3.UnitY * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.Right) > 0) { camera.rotation *= Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0.00015f); } if (GLFWInput.TimeKeyPressed(Keys.Left) > 0) { camera.rotation *= Quaternion.CreateFromAxisAngle(Vector3.UnitY, -0.00015f); } uint imageIndex = 0; Assert(vkAcquireNextImageKHR(device, swapchain, ulong.MaxValue, acquireSemaphore, VkFence.Null, &imageIndex)); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; voxelPipeline.swapchainFramebuffer = frambuffers[imageIndex]; voxelPipeline.swapchainImage = swapchainImages[imageIndex]; voxelPipeline.swapchainImageIndex = imageIndex; voxelPipeline.mesh = mesh; voxelPipeline.camera = camera; fixed(VkFence *ptr = &(fences[imageIndex])) { vkWaitForFences(device, 1, ptr, VkBool32.False, ulong.MaxValue); vkResetFences(device, 1, ptr); } cmdBuffers[imageIndex].RecordCommandBuffer(new Action <VkCommandBuffer>[] { voxelPipeline.Execute, }); VkPipelineStageFlags submitStageMask = VkPipelineStageFlags.ColorAttachmentOutput; VkSubmitInfo submitInfo = VkSubmitInfo.New(); submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = &acquireSemaphore; submitInfo.pWaitDstStageMask = &submitStageMask; submitInfo.commandBufferCount = 1; fixed(VkCommandBuffer *ptr = &(cmdBuffers[imageIndex].buffer)) submitInfo.pCommandBuffers = ptr; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &releaseSemaphore; Assert(vkQueueSubmit(graphicsQueue, 1, &submitInfo, fences[imageIndex])); VkPresentInfoKHR presentInfoKHR = VkPresentInfoKHR.New(); presentInfoKHR.swapchainCount = 1; presentInfoKHR.pSwapchains = &swapchain; presentInfoKHR.pImageIndices = &imageIndex; presentInfoKHR.waitSemaphoreCount = 1; presentInfoKHR.pWaitSemaphores = &releaseSemaphore; Assert(vkQueuePresentKHR(graphicsQueue, &presentInfoKHR)); vkDeviceWaitIdle(device); } finst.Destroy(); DestroyWindow(window); Terminate(); }