void CreateStagingBuffer() { long imageSize = imageWidth * imageHeight * 4; CreateBuffer(imageSize, VkBufferUsageFlags.TransferSrcBit, VkMemoryPropertyFlags.HostVisibleBit | VkMemoryPropertyFlags.HostCoherentBit, out stagingBuffer, out stagingBufferMemory); stagingBufferPtr = stagingBufferMemory.Map(0, imageSize); //DeviceMemory is implicitly unmapped when it is freed }
void CreateUniformBuffer() { long bufferSize = Interop.SizeOf <UniformBufferObject>(); CreateBuffer(bufferSize, VkBufferUsageFlags.UniformBufferBit, VkMemoryPropertyFlags.HostVisibleBit | VkMemoryPropertyFlags.HostCoherentBit, out uniformBuffer, out uniformBufferMemory); uniformBufferPtr = uniformBufferMemory.Map(0, bufferSize); }
void UpdateUniformBuffer() { double time = watch.Elapsed.TotalSeconds; var ubo = new UniformBufferObject(); ubo.model = Matrix4x4.CreateRotationZ((float)(time * Math.PI / 2)); ubo.view = Matrix4x4.CreateLookAt(new Vector3(2, 2, 2), new Vector3(0, 0, 0), new Vector3(0, 0, 1)); ubo.proj = Matrix4x4.CreatePerspectiveFieldOfView((float)Math.PI / 4, swapchainExtent.width / (float)swapchainExtent.height, 0.1f, 10f); ubo.proj.M22 *= -1; long size = Interop.SizeOf <UniformBufferObject>(); var data = uniformBufferMemory.Map(0, size); Interop.Copy(new UniformBufferObject[] { ubo }, data); uniformBufferMemory.Unmap(); }
public Framebuffer(VkDevice Device, int Width, int Height) { _Device = Device; _Width = Width; _Height = Height; _FrameBufferColor = _Device.CreateImage(VkImageCreateFlag.NONE, VkFormat.VK_FORMAT_B8G8R8A8_SRGB, Width, Height, 1, 1, VkSampleCountFlag.VK_SAMPLE_COUNT_1, VkImageTiling.VK_IMAGE_TILING_OPTIMAL, VkImageUsageFlag.VK_IMAGE_USAGE_COLOR_ATTACHMENT, VkSharingMode.VK_SHARING_MODE_EXCLUSIVE, null, VkImageLayout.VK_IMAGE_LAYOUT_UNDEFINED); _ImageSize = _FrameBufferColor.MemoryRequirements.size; // We will back this image with Device Accessible Memomy so we can map it an copy // the content from the Host. // To do so we need to find the right memory type first. VkMemoryType deviceMemory = new VkMemoryType(); foreach (VkMemoryType memoryType in _FrameBufferColor.MemoryRequirements.memoryTypes) { // Pick the first memory type that can be mapped into host memory if ((memoryType.propertyFlags & VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_DEVICE_LOCAL) != 0) { deviceMemory = memoryType; break; } } VkDeviceMemory FrameBufferMemory = _Device.AllocateMemory(_FrameBufferColor.MemoryRequirements.size, deviceMemory); _FrameBufferColor.BindMemory(FrameBufferMemory, 0); // Allocate the host visible memory to transfer the framebuffer _TransferBuffer = _Device.CreateBuffer(0, _FrameBufferColor.MemoryRequirements.size, VkBufferUsageFlag.VK_BUFFER_USAGE_TRANSFER_DST, VkSharingMode.VK_SHARING_MODE_EXCLUSIVE, new VkQueueFamilyProperties[] { _Device.Queues[0].Family }); // We will use a host visible buffer so we can map it an copy // the content from the Host. // To do so we need to find the right memory type first. VkMemoryType hostMemory = new VkMemoryType(); foreach (VkMemoryType memoryType in _TransferBuffer.MemoryRequirements.memoryTypes) { // Pick the first memory type that can be mapped into host memory if ((memoryType.propertyFlags & VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_VISIBLE) != 0) { hostMemory = memoryType; break; } } VkDeviceMemory TransferBufferMemory = _Device.AllocateMemory(_ImageSize, hostMemory); _TransferBuffer.BindMemory(TransferBufferMemory, 0); _TransferBufferPtr = TransferBufferMemory.Map(0, _ImageSize, VkMemoryMapFlag.NONE); VkImageView imageView = _FrameBufferColor.CreateImageView(VkImageViewType.VK_IMAGE_VIEW_TYPE_2D, new VkImageSubresourceRange() { aspectMask = VkImageAspectFlag.VK_IMAGE_ASPECT_COLOR_BIT, baseArrayLayer = 0, baseMipLevel = 0, layerCount = 1, levelCount = 1 }); VkAttachmentDescription colorAttachment = new VkAttachmentDescription(); colorAttachment.format = _FrameBufferColor.Format; colorAttachment.samples = VkSampleCountFlag.VK_SAMPLE_COUNT_1; colorAttachment.loadOp = VkAttachmentLoadOp.VK_ATTACHMENT_LOAD_OP_CLEAR; colorAttachment.storeOp = VkAttachmentStoreOp.VK_ATTACHMENT_STORE_OP_STORE; colorAttachment.stencilLoadOp = VkAttachmentLoadOp.VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorAttachment.stencilStoreOp = VkAttachmentStoreOp.VK_ATTACHMENT_STORE_OP_DONT_CARE; colorAttachment.initialLayout = VkImageLayout.VK_IMAGE_LAYOUT_UNDEFINED; colorAttachment.finalLayout = VkImageLayout.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; VkAttachmentReference colorAttachmentReference = new VkAttachmentReference(); colorAttachmentReference.attachment = 0; colorAttachmentReference.layout = VkImageLayout.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; VkSubpassDescription subpass = new VkSubpassDescription(); subpass.pipelineBindPoint = VkPipelineBindPoint.VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachments = new VkAttachmentReference[] { colorAttachmentReference }; subpass.depthStencilAttachment = null; subpass.inputAttachments = null; subpass.preserveAttachments = null; subpass.resolveAttachments = null; VkSubpassDependency dependency = new VkSubpassDependency(); dependency.srcSubpass = VkSubpassDependency.VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VkPipelineStageFlag.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT; dependency.srcAccessMask = 0; dependency.dstStageMask = VkPipelineStageFlag.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT; dependency.dstAccessMask = VkAccessFlag.VK_ACCESS_COLOR_ATTACHMENT_READ | VkAccessFlag.VK_ACCESS_COLOR_ATTACHMENT_WRITE; _RenderPass = _Device.CreateRenderPass(new VkAttachmentDescription[] { colorAttachment }, new VkSubpassDescription[] { subpass }, new VkSubpassDependency[] { dependency }); _Framebuffer = _Device.CreateFramebuffer(_RenderPass, new VkImageView[] { imageView }, (uint)Width, (uint)Height, 1); }
public ClearImage() { InitializeComponent(); _Bitmap = new Bitmap(640, 480); // Create the VUlkan instance that we will use for this app _Instance = new VkInstance("ClearImage - 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; } } // Now it is time to create the image that we will fill wih the solid color _Image = _Device.CreateImage( VkImageCreateFlag.NONE, VkFormat.VK_FORMAT_B8G8R8A8_SRGB, _Bitmap.Width, _Bitmap.Height, 1, 1, VkSampleCountFlag.VK_SAMPLE_COUNT_1, VkImageTiling.VK_IMAGE_TILING_LINEAR, VkImageUsageFlag.VK_IMAGE_USAGE_TRANSFER_SRC | VkImageUsageFlag.VK_IMAGE_USAGE_TRANSFER_DST, VkSharingMode.VK_SHARING_MODE_EXCLUSIVE, null, VkImageLayout.VK_IMAGE_LAYOUT_GENERAL); // We will back this image with Host Accessible Memomy so we can map it an copy // the content from the Host. // To do so we need to find the right memory type first. VkMemoryType HostMemory = new VkMemoryType(); foreach (VkMemoryType memoryType in _Image.MemoryRequirements.memoryTypes) { // Pick the first memory type that can be mapped into host memory if ((memoryType.propertyFlags & VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_VISIBLE) != 0) { HostMemory = memoryType; break; } } // Allocate the backing memory for this image VkDeviceMemory Memory = _Device.AllocateMemory(_Image.MemoryRequirements.size, HostMemory); _Image.BindMemory(Memory, 0); // Create the CPU mapping _ImagePtr = Memory.Map(0, _Image.MemoryRequirements.size, VkMemoryMapFlag.NONE); // Now we need to create a command buffer and we will fill it with a single command: // Fill the image with the color (0.1f, 0.75f, 1.0f, 1.0f) which is a Sky blue. VkCommandPool Pool = _Device.CreateCommandPool(VkCommandPoolCreateFlag.NONE, _Queue.Family); _CommandBuffer = Pool.AllocateCommandBuffer(VkCommandBufferLevel.VK_COMMAND_BUFFER_LEVEL_PRIMARY); _CommandBuffer.Begin(VkCommandBufferUsageFlag.NONE); _CommandBuffer.CmdClearColorImage( _Image, VkImageLayout.VK_IMAGE_LAYOUT_GENERAL, 0.1f, 0.75f, 1.0f, 1.0f, new VkImageSubresourceRange[] { new VkImageSubresourceRange() { aspectMask = VkImageAspectFlag.VK_IMAGE_ASPECT_COLOR_BIT, baseArrayLayer = 0, baseMipLevel = 0, layerCount = 1, levelCount = 1 } }); _CommandBuffer.End(); // Finally we will need a fence for our submission in order to wait on it _Fence = _Device.CreateFence(VkFenceCreateFlag.NONE); break; } } } }