public override void Begin() { if (_commandBufferBegun) { throw new VeldridException( "CommandList must be in its initial state, or End() must have been called, for Begin() to be valid to call."); } if (_commandBufferEnded) { _commandBufferEnded = false; _cb = GetNextCommandBuffer(); if (_currentStagingInfo != null) { RecycleStagingInfo(_currentStagingInfo); } } _currentStagingInfo = GetStagingResourceInfo(); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; vkBeginCommandBuffer(_cb, ref beginInfo); _commandBufferBegun = true; ClearCachedState(); _currentFramebuffer = null; _currentGraphicsPipeline = null; Util.ClearArray(_currentGraphicsResourceSets); Util.ClearArray(_scissorRects); _currentComputePipeline = null; Util.ClearArray(_currentComputeResourceSets); }
public void RecordCommandBuffer(Action <VkCommandBuffer>[] executions) { Assert(vkResetCommandBuffer(buffer, VkCommandBufferResetFlags.None)); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; Assert(vkBeginCommandBuffer(buffer, &beginInfo)); for (int i = 0; i < executions.Length; i++) { executions[i](buffer); } Assert(vkEndCommandBuffer(buffer)); }
public override void Begin() { if (_commandBufferBegun) { throw new VeldridException( "CommandList must be in it's initial state, or End() must have been called, for Begin() to be valid to call."); } if (_commandBufferEnded) { _commandBufferEnded = false; vkResetCommandPool(_gd.Device, _pool, VkCommandPoolResetFlags.None); } VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); vkBeginCommandBuffer(_cb, ref beginInfo); _commandBufferBegun = true; }
protected VkCommandBuffer BeginOneTimeCommands() { VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo.New(); allocInfo.commandBufferCount = 1; allocInfo.commandPool = _rc.GraphicsCommandPool; allocInfo.level = VkCommandBufferLevel.Primary; vkAllocateCommandBuffers(_device, ref allocInfo, out VkCommandBuffer cb); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; vkBeginCommandBuffer(cb, ref beginInfo); return(cb); }
public VkCommandBuffer BeginNewCommandBuffer() { VkCommandBufferAllocateInfo allocateInfo = VkCommandBufferAllocateInfo.New(); allocateInfo.commandBufferCount = 1; allocateInfo.level = VkCommandBufferLevel.Primary; allocateInfo.commandPool = _pool; VkResult result = vkAllocateCommandBuffers(_gd.Device, ref allocateInfo, out VkCommandBuffer cb); CheckResult(result); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; result = vkBeginCommandBuffer(cb, ref beginInfo); CheckResult(result); return(cb); }
public VkCommandBuffer createCommandBuffer(VkCommandBufferLevel level, bool begin = false) { VkCommandBufferAllocateInfo cmdBufAllocateInfo = VkCommandBufferAllocateInfo.New(); cmdBufAllocateInfo.commandPool = CommandPool; cmdBufAllocateInfo.level = level; cmdBufAllocateInfo.commandBufferCount = 1; VkCommandBuffer cmdBuffer; Util.CheckResult(vkAllocateCommandBuffers(_logicalDevice, ref cmdBufAllocateInfo, out cmdBuffer)); // If requested, also start recording for the new command buffer if (begin) { VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.New(); Util.CheckResult(vkBeginCommandBuffer(cmdBuffer, ref cmdBufInfo)); } return(cmdBuffer); }
public override void Begin() { if (_commandBufferBegun) { throw new VeldridException( "CommandList must be in its initial state, or End() must have been called, for Begin() to be valid to call."); } if (_commandBufferEnded) { _commandBufferEnded = false; vkResetCommandPool(_gd.Device, _pool, VkCommandPoolResetFlags.None); } VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); vkBeginCommandBuffer(_cb, ref beginInfo); _commandBufferBegun = true; ClearCachedState(); _currentFramebuffer = null; _currentGraphicsPipeline = null; Util.ClearArray(_currentGraphicsResourceSets); Util.ClearArray(_scissorRects); _currentComputePipeline = null; Util.ClearArray(_currentComputeResourceSets); _referencedResources.Clear(); foreach (VkBuffer vkBuffer in _usedStagingBuffers) { _availableStagingBuffers.Add(vkBuffer); } _usedStagingBuffers.Clear(); }
protected override void buildCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.New(); FixedArray2 <VkClearValue> clearValues = new FixedArray2 <VkClearValue>(); clearValues.First.color = defaultClearColor; clearValues.Second.depthStencil = new VkClearDepthStencilValue() { depth = 1f, stencil = 0 }; VkRenderPassBeginInfo renderPassBeginInfo = VkRenderPassBeginInfo.New(); renderPassBeginInfo.renderPass = RenderPass; renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.y = 0; renderPassBeginInfo.renderArea.extent.width = Width; renderPassBeginInfo.renderArea.extent.height = Height; renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.pClearValues = (VkClearValue *)Unsafe.AsPointer(ref clearValues); for (int i = 0; i < DrawCmdBuffers.Count; ++i) { // Set target frame buffer renderPassBeginInfo.framebuffer = Framebuffers[i]; Util.CheckResult(vkBeginCommandBuffer(DrawCmdBuffers[i], ref cmdBufInfo)); vkCmdBeginRenderPass(DrawCmdBuffers[i], ref renderPassBeginInfo, VkSubpassContents.Inline); VkViewport viewport = new VkViewport() { width = Width, height = Height, minDepth = 0f, maxDepth = 1f }; vkCmdSetViewport(DrawCmdBuffers[i], 0, 1, ref viewport); VkRect2D scissor = new VkRect2D() { extent = new VkExtent2D() { width = Width, height = Height }, offset = new VkOffset2D() }; vkCmdSetScissor(DrawCmdBuffers[i], 0, 1, ref scissor); vkCmdBindDescriptorSets(DrawCmdBuffers[i], VkPipelineBindPoint.Graphics, pipelineLayout, 0, 1, ref descriptorSet, 0, null); ulong offsets = 0; vkCmdBindVertexBuffers(DrawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, ref models_cube.vertices.buffer, ref offsets); vkCmdBindIndexBuffer(DrawCmdBuffers[i], models_cube.indices.buffer, 0, VkIndexType.Uint32); // Left : Solid colored viewport.width = Width / 3.0f; vkCmdSetViewport(DrawCmdBuffers[i], 0, 1, &viewport); vkCmdBindPipeline(DrawCmdBuffers[i], VkPipelineBindPoint.Graphics, pipelines_phong); vkCmdDrawIndexed(DrawCmdBuffers[i], models_cube.indexCount, 1, 0, 0, 0); // Center : Toon viewport.x = Width / 3.0f; vkCmdSetViewport(DrawCmdBuffers[i], 0, 1, &viewport); vkCmdBindPipeline(DrawCmdBuffers[i], VkPipelineBindPoint.Graphics, pipelines_toon); // Line Width > 1.0f only if wide lines feature is supported if (DeviceFeatures.wideLines != 0) { vkCmdSetLineWidth(DrawCmdBuffers[i], 2.0f); } vkCmdDrawIndexed(DrawCmdBuffers[i], models_cube.indexCount, 1, 0, 0, 0); if (DeviceFeatures.fillModeNonSolid != 0) { // Right : Wireframe viewport.x = Width / 3.0f + Width / 3.0f; vkCmdSetViewport(DrawCmdBuffers[i], 0, 1, &viewport); vkCmdBindPipeline(DrawCmdBuffers[i], VkPipelineBindPoint.Graphics, pipelines_wireframe); vkCmdDrawIndexed(DrawCmdBuffers[i], models_cube.indexCount, 1, 0, 0, 0); } vkCmdEndRenderPass(DrawCmdBuffers[i]); Util.CheckResult(vkEndCommandBuffer(DrawCmdBuffers[i])); } }
private static void InitMips(VkDevice device, VkQueue queue, VkImage image, int width, int height, uint mipLevels, uint layerCount, int cmdPool) { VkCommandBufferAllocateInfo pAllocateInfo = VkCommandBufferAllocateInfo.New(); pAllocateInfo.commandPool = CommandPoolManager.GetPool(cmdPool); pAllocateInfo.level = VkCommandBufferLevel.Primary; pAllocateInfo.commandBufferCount = 1; VkCommandBuffer cmdBuffer = VkCommandBuffer.Null; Assert(vkAllocateCommandBuffers(device, &pAllocateInfo, &cmdBuffer)); Assert(vkResetCommandBuffer(cmdBuffer, VkCommandBufferResetFlags.None)); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; Assert(vkBeginCommandBuffer(cmdBuffer, &beginInfo)); VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New(); imageMemoryBarrier.srcAccessMask = VkAccessFlags.None; imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferWrite; imageMemoryBarrier.oldLayout = VkImageLayout.Undefined; imageMemoryBarrier.newLayout = VkImageLayout.TransferDstOptimal; imageMemoryBarrier.srcQueueFamilyIndex = VulkanNative.QueueFamilyIgnored; imageMemoryBarrier.dstQueueFamilyIndex = VulkanNative.QueueFamilyIgnored; imageMemoryBarrier.image = image; imageMemoryBarrier.subresourceRange = new VkImageSubresourceRange() { baseMipLevel = 0, levelCount = mipLevels, baseArrayLayer = 0, layerCount = layerCount, aspectMask = VkImageAspectFlags.Color }; vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion, 0, null, 0, null, 1, &imageMemoryBarrier); for (int i = 1; i < mipLevels; i++) { imageMemoryBarrier.oldLayout = VkImageLayout.TransferDstOptimal; imageMemoryBarrier.newLayout = VkImageLayout.TransferSrcOptimal; imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferWrite; imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferRead; imageMemoryBarrier.subresourceRange.baseMipLevel = (uint)(i - 1); imageMemoryBarrier.subresourceRange.levelCount = 1; vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion, 0, null, 0, null, 1, &imageMemoryBarrier); VkImageBlit blit = new VkImageBlit(); blit.srcOffsets_0 = new VkOffset3D { x = 0, y = 0, z = 0 }; blit.srcOffsets_1 = new VkOffset3D { x = width, y = height, z = 1 }; blit.srcSubresource.aspectMask = VkImageAspectFlags.Color; blit.srcSubresource.mipLevel = (uint)(i - 1); blit.srcSubresource.baseArrayLayer = 0; blit.srcSubresource.layerCount = layerCount; blit.dstOffsets_0 = new VkOffset3D { x = 0, y = 0, z = 0 }; blit.dstOffsets_1 = new VkOffset3D { x = width / 2, y = height / 2, z = 1 }; blit.dstSubresource.aspectMask = VkImageAspectFlags.Color; blit.dstSubresource.mipLevel = (uint)i; blit.dstSubresource.baseArrayLayer = 0; blit.dstSubresource.layerCount = layerCount; vkCmdBlitImage(cmdBuffer, image, VkImageLayout.TransferSrcOptimal, image, VkImageLayout.TransferDstOptimal, 1, &blit, VkFilter.Linear); width /= 2; height /= 2; imageMemoryBarrier.oldLayout = VkImageLayout.TransferSrcOptimal; imageMemoryBarrier.newLayout = VkImageLayout.ShaderReadOnlyOptimal; imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead; imageMemoryBarrier.dstAccessMask = VkAccessFlags.ShaderRead; imageMemoryBarrier.subresourceRange.baseMipLevel = (uint)(i - 1); imageMemoryBarrier.subresourceRange.levelCount = 1; vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion, 0, null, 0, null, 1, &imageMemoryBarrier); } imageMemoryBarrier.oldLayout = VkImageLayout.Undefined; imageMemoryBarrier.newLayout = VkImageLayout.ShaderReadOnlyOptimal; imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead; imageMemoryBarrier.dstAccessMask = VkAccessFlags.ShaderRead; imageMemoryBarrier.subresourceRange.baseMipLevel = mipLevels - 1; imageMemoryBarrier.subresourceRange.levelCount = 1; vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion, 0, null, 0, null, 1, &imageMemoryBarrier); Assert(vkEndCommandBuffer(cmdBuffer)); VkSubmitInfo submitInfo = VkSubmitInfo.New(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cmdBuffer; Assert(vkQueueSubmit(queue, 1, &submitInfo, VkFence.Null)); }
private static VkImage LoadTexture(VkDevice device, VkPhysicalDevice physicalDevice, int cmdPoolID, VkQueue queue, string[] paths, uint mipLevels) { Bitmap[] bitmaps = new Bitmap[paths.Length]; FDataBuffer <byte>[] tempBuffer = new FDataBuffer <byte> [paths.Length]; uint width = 0, height = 0; for (int j = 0; j < paths.Length; j++) { bitmaps[j] = new Bitmap(System.Drawing.Image.FromFile(paths[j])); var data = bitmaps[j].LockBits(new Rectangle(0, 0, bitmaps[j].Width, bitmaps[j].Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmaps[j].PixelFormat); width = (uint)data.Width; height = (uint)data.Height;//TODO add size check Span <byte> img = new Span <byte>((void *)data.Scan0, data.Stride * data.Height); tempBuffer[j] = new FDataBuffer <byte>(device, physicalDevice, img.Length, VkBufferUsageFlags.TransferSrc, VkSharingMode.Exclusive); Span <byte> buffer = tempBuffer[j].Map(); for (int i = 0; i < img.Length; i += 4) { buffer[i + 2] = img[i]; buffer[i + 1] = img[i + 1]; buffer[i] = img[i + 2]; buffer[i + 3] = img[i + 3]; } buffer = tempBuffer[j].UnMap(); } VkImage texture = VkImage.Null; VkDeviceMemory memory = VkDeviceMemory.Null; VkImageCreateInfo createInfo = VkImageCreateInfo.New(); createInfo.imageType = VkImageType.Image2D; createInfo.extent.width = width; createInfo.extent.height = height; createInfo.extent.depth = 1; createInfo.mipLevels = mipLevels; createInfo.arrayLayers = (uint)paths.Length; createInfo.format = VkFormat.R8g8b8a8Unorm; createInfo.tiling = VkImageTiling.Optimal; createInfo.initialLayout = VkImageLayout.Undefined; createInfo.usage = VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferSrc; createInfo.sharingMode = VkSharingMode.Exclusive; createInfo.samples = VkSampleCountFlags.Count1; Assert(vkCreateImage(device, &createInfo, null, &texture)); VkMemoryRequirements memoryRequirements; vkGetImageMemoryRequirements(device, texture, &memoryRequirements); VkPhysicalDeviceMemoryProperties memoryProperties = new VkPhysicalDeviceMemoryProperties(); vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties); VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New(); allocateInfo.allocationSize = memoryRequirements.size; allocateInfo.memoryTypeIndex = FDataBuffer <byte> .SelectMemoryType(memoryProperties, memoryRequirements.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal); Assert(vkAllocateMemory(device, &allocateInfo, null, &memory)); vkBindImageMemory(device, texture, memory, 0); VkCommandBufferAllocateInfo pAllocateInfo = VkCommandBufferAllocateInfo.New(); pAllocateInfo.commandPool = CommandPoolManager.GetPool(cmdPoolID); pAllocateInfo.level = VkCommandBufferLevel.Primary; pAllocateInfo.commandBufferCount = 1; VkCommandBuffer cmdBuffer = VkCommandBuffer.Null; Assert(vkAllocateCommandBuffers(device, &pAllocateInfo, &cmdBuffer)); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; Assert(vkBeginCommandBuffer(cmdBuffer, &beginInfo)); VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New(); imageMemoryBarrier.srcAccessMask = VkAccessFlags.None; imageMemoryBarrier.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite; imageMemoryBarrier.oldLayout = VkImageLayout.Undefined; imageMemoryBarrier.newLayout = VkImageLayout.TransferDstOptimal; imageMemoryBarrier.srcQueueFamilyIndex = VulkanNative.QueueFamilyIgnored; imageMemoryBarrier.dstQueueFamilyIndex = VulkanNative.QueueFamilyIgnored; imageMemoryBarrier.image = texture; imageMemoryBarrier.subresourceRange = new VkImageSubresourceRange() { baseMipLevel = 0, levelCount = mipLevels, baseArrayLayer = 0, layerCount = (uint)paths.Length, aspectMask = VkImageAspectFlags.Color }; vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion, 0, null, 0, null, 1, &imageMemoryBarrier); for (int j = 0; j < tempBuffer.Length; j++) { VkBufferImageCopy region = new VkBufferImageCopy(); region.bufferOffset = 0; region.bufferRowLength = 0; region.bufferImageHeight = 0; region.imageSubresource.aspectMask = VkImageAspectFlags.Color; region.imageSubresource.mipLevel = 0; region.imageSubresource.baseArrayLayer = (uint)j; region.imageSubresource.layerCount = 1; region.imageOffset = new VkOffset3D(); region.imageExtent = new VkExtent3D() { width = width, height = height, depth = 1 }; vkCmdCopyBufferToImage(cmdBuffer, tempBuffer[j].Buffer, texture, VkImageLayout.TransferDstOptimal, 1, ®ion); } imageMemoryBarrier.oldLayout = VkImageLayout.TransferDstOptimal; imageMemoryBarrier.newLayout = VkImageLayout.ShaderReadOnlyOptimal; vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion, 0, null, 0, null, 1, &imageMemoryBarrier); Assert(vkEndCommandBuffer(cmdBuffer)); VkSubmitInfo submitInfo = VkSubmitInfo.New(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cmdBuffer; Assert(vkQueueSubmit(queue, 1, &submitInfo, VkFence.Null)); Assert(vkQueueWaitIdle(queue)); vkFreeCommandBuffers(device, CommandPoolManager.GetPool(cmdPoolID), 1, &cmdBuffer); return(texture); }
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(); }
private void FlushFrameDrawCommands() { _scInfo.AcquireNextImage(_device, _imageAvailableSemaphore); for (int i = 0; i < _renderPassStates.Count; i++) { RenderPassInfo renderPassState = _renderPassStates[i]; VkCommandBuffer primaryCommandBuffer = GetPrimaryCommandBuffer(); renderPassState.PrimaryCommandBuffer = primaryCommandBuffer; VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; vkBeginCommandBuffer(primaryCommandBuffer, ref beginInfo); VkRenderPassBeginInfo renderPassBeginInfo = VkRenderPassBeginInfo.New(); VkFramebufferBase fbInfo = renderPassState.Framebuffer; renderPassBeginInfo.framebuffer = fbInfo.VkFramebuffer; renderPassBeginInfo.renderPass = renderPassState.ClearBuffer ? fbInfo.RenderPassClearBuffer : fbInfo.RenderPassNoClear; if (renderPassState.ClearBuffer) { VkClearColorValue colorClear = new VkClearColorValue { float32_0 = renderPassState.ClearColor.R, float32_1 = renderPassState.ClearColor.G, float32_2 = renderPassState.ClearColor.B, float32_3 = renderPassState.ClearColor.A }; VkClearDepthStencilValue depthClear = new VkClearDepthStencilValue() { depth = 1f, stencil = 0 }; StackList <VkClearValue, Size512Bytes> clearValues = new StackList <VkClearValue, Size512Bytes>(); if (fbInfo.ColorTexture != null) { clearValues.Add(new VkClearValue() { color = colorClear }); } if (fbInfo.DepthTexture != null) { clearValues.Add(new VkClearValue() { depthStencil = depthClear }); } renderPassBeginInfo.clearValueCount = clearValues.Count; renderPassBeginInfo.pClearValues = (VkClearValue *)clearValues.Data; } renderPassBeginInfo.renderArea.extent = new VkExtent2D(fbInfo.Width, fbInfo.Height); vkCmdBeginRenderPass(primaryCommandBuffer, ref renderPassBeginInfo, VkSubpassContents.SecondaryCommandBuffers); RawList <VkCommandBuffer> secondaryCBs = renderPassState.SecondaryCommandBuffers; if (secondaryCBs.Count > 0) { vkCmdExecuteCommands(primaryCommandBuffer, secondaryCBs.Count, ref secondaryCBs[0]); } vkCmdEndRenderPass(primaryCommandBuffer); vkEndCommandBuffer(primaryCommandBuffer); VkSubmitInfo submitInfo = VkSubmitInfo.New(); VkSemaphore waitSemaphore = (i == 0) ? _imageAvailableSemaphore : _renderPassSemaphores[i - 1]; VkPipelineStageFlags waitStages = VkPipelineStageFlags.ColorAttachmentOutput; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = &waitSemaphore; submitInfo.pWaitDstStageMask = &waitStages; VkCommandBuffer cb = primaryCommandBuffer; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cb; VkSemaphore signalSemaphore = _renderPassSemaphores[i]; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &signalSemaphore; vkQueueSubmit(_graphicsQueue, 1, ref submitInfo, VkFence.Null); } }
private void DrawPrimitives(int indexCount, int instanceCount, int startingIndex, int startingVertex) { RenderPassInfo renderPassState = GetCurrentRenderPass(); VkPipelineLayout layout = ShaderResourceBindingSlots.PipelineLayout; VkPipelineCacheKey pipelineCacheKey = new VkPipelineCacheKey(); pipelineCacheKey.RenderPass = renderPassState.Framebuffer.RenderPassClearBuffer; pipelineCacheKey.PipelineLayout = layout; pipelineCacheKey.BlendState = (VkBlendState)BlendState; pipelineCacheKey.Framebuffer = renderPassState.Framebuffer; pipelineCacheKey.DepthStencilState = (VkDepthStencilState)DepthStencilState; pipelineCacheKey.RasterizerState = (VkRasterizerState)RasterizerState; pipelineCacheKey.PrimitiveTopology = _primitiveTopology; pipelineCacheKey.ShaderSet = ShaderSet; pipelineCacheKey.VertexBindings = VertexBuffers; VkPipeline graphicsPipeline = _resourceCache.GetGraphicsPipeline(ref pipelineCacheKey); VkDescriptorSetCacheKey descriptorSetCacheKey = new VkDescriptorSetCacheKey(); descriptorSetCacheKey.ShaderResourceBindingSlots = ShaderResourceBindingSlots; descriptorSetCacheKey.ConstantBuffers = _constantBuffers; descriptorSetCacheKey.TextureBindings = _textureBindings; descriptorSetCacheKey.SamplerStates = _samplerStates; VkDescriptorSet descriptorSet = _resourceCache.GetDescriptorSet(ref descriptorSetCacheKey); VkCommandBuffer cb = GetCommandBuffer(); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit | VkCommandBufferUsageFlags.RenderPassContinue; VkCommandBufferInheritanceInfo inheritanceInfo = VkCommandBufferInheritanceInfo.New(); inheritanceInfo.renderPass = renderPassState.Framebuffer.RenderPassClearBuffer; beginInfo.pInheritanceInfo = &inheritanceInfo; vkBeginCommandBuffer(cb, ref beginInfo); vkCmdBindPipeline(cb, VkPipelineBindPoint.Graphics, graphicsPipeline); vkCmdBindDescriptorSets( cb, VkPipelineBindPoint.Graphics, layout, 0, 1, ref descriptorSet, 0, IntPtr.Zero); int vbCount = ShaderSet.InputLayout.InputDescriptions.Length; StackList <VkBuffer, Size512Bytes> vbs = new StackList <VkBuffer, Size512Bytes>(); for (int vbIndex = 0; vbIndex < vbCount; vbIndex++) { vbs.Add(((VkVertexBuffer)VertexBuffers[vbIndex]).DeviceBuffer); } StackList <VkBuffer, Size512Bytes> offsets = new StackList <VkBuffer, Size512Bytes>(); vkCmdBindVertexBuffers(cb, 0, vbs.Count, (IntPtr)vbs.Data, (IntPtr)offsets.Data); vkCmdBindIndexBuffer(cb, IndexBuffer.DeviceBuffer, 0, IndexBuffer.IndexType); VkViewport viewport = new VkViewport() { x = Viewport.X, y = Viewport.Y, width = Viewport.Width, height = Viewport.Height, minDepth = 0, maxDepth = 1 }; vkCmdSetViewport(cb, 0, 1, ref viewport); vkCmdSetScissor(cb, 0, 1, ref _scissorRect); vkCmdDrawIndexed(cb, (uint)indexCount, (uint)instanceCount, (uint)startingIndex, startingVertex, 0); vkEndCommandBuffer(cb); renderPassState.SecondaryCommandBuffers.Add(cb); }