public static Texture2D RenderTarget(Graphics g, int width, int height) { const Format format = Format.B8G8R8A8UNorm; // Create optimal tiled target image. Image image = g.Context.Device.CreateImage(new ImageCreateInfo { ImageType = ImageType.Image2D, Format = format, MipLevels = 1, ArrayLayers = 1, Samples = SampleCounts.Count1, Tiling = ImageTiling.Optimal, SharingMode = SharingMode.Exclusive, InitialLayout = ImageLayout.Undefined, Extent = new Extent3D(width, height, 1), Usage = ImageUsages.Sampled | ImageUsages.TransferDst | ImageUsages.TransferSrc | ImageUsages.ColorAttachment }); MemoryRequirements imageMemReq = image.GetMemoryRequirements(); int imageHeapIndex = g.Context.MemoryProperties.MemoryTypes.IndexOf( imageMemReq.MemoryTypeBits, MemoryProperties.DeviceLocal); DeviceMemory memory = g.Context.Device.AllocateMemory(new MemoryAllocateInfo(imageMemReq.Size, imageHeapIndex)); image.BindMemory(memory); var subresourceRange = new ImageSubresourceRange(ImageAspects.Color, 0, 1, 0, 1); // Create image view. ImageView view = image.CreateView(new ImageViewCreateInfo(format, subresourceRange)); var sampler = VKHelper.CreateSampler(g.Context, Filter.Linear, Filter.Linear, SamplerMipmapMode.Linear); return(new Texture2D(g.Context, image, memory, view, format, new Vector2I(width, height), true)); }
internal void Build() { GraphicsCommandPool?.Reset(); ComputeCommandPool?.Reset(); ImageAvailableSemaphore?.Dispose(); RenderingFinishedSemaphore?.Dispose(); Swapchain?.Dispose(); ImageAvailableSemaphore = ToDispose(Device.CreateSemaphore()); RenderingFinishedSemaphore = ToDispose(Device.CreateSemaphore()); Swapchain = ToDispose(VKHelper.CreateSwapchain(this)); CacheSwapchainImages(); }
public void Build() { DescriptorSetLayout?.Dispose(); PipelineLayout?.Dispose(); //UsingSamplers?.DisposeRange(); DescriptorPool?.Dispose(); RenderPass?.Dispose(); Pipeline?.Dispose(); DescriptorSetLayout = VKHelper.CreateDescriptorSetLayout(Graphics, DescriptorItems); PipelineLayout = VKHelper.CreatePipelineLayout(Graphics, DescriptorSetLayout); DescriptorPool = VKHelper.CreateDescriptorPool(Graphics, DescriptorItems); DescriptorSet = VKHelper.CreateDescriptorSet(DescriptorPool, DescriptorSetLayout, DescriptorItems, out UsingSamplers); RenderPass = VKHelper.CreateRenderPass(Graphics, ClearDepthOnBeginPass); Pipeline = VKHelper.CreateGraphicsPipeline(Graphics, PipelineLayout, RenderPass, Shaders, DepthTest, DepthWrite, Instancing, InstanceInfoType, BlendMode, PrimitiveType, PrimitiveRenderMode, PrimitiveCullMode, LineWidth, ViewportPos, ViewportSize); }
public static DescriptorItem CombinedImageSampler(ShaderType shaderType, Texture2D texture, SamplerFilter minFilter, SamplerFilter magFilter, SamplerFilter mipmapFilter = SamplerFilter.Nearest) { var item = new DescriptorItem(); item.Type = DescriptorType.CombinedImageSampler; item.Shader = shaderType; item.Texture = texture; item.Sampler = VKHelper.CreateSampler( texture.Context, minFilter == SamplerFilter.Nearest ? Filter.Nearest : minFilter == SamplerFilter.Cubic ? Filter.CubicImg : Filter.Linear, magFilter == SamplerFilter.Nearest ? Filter.Nearest : magFilter == SamplerFilter.Cubic ? Filter.CubicImg : Filter.Linear, mipmapFilter == SamplerFilter.Linear ? SamplerMipmapMode.Linear : SamplerMipmapMode.Nearest ); return(item); }
public Context(GameWindow window) { Window = window; Instance = ToDispose(VKHelper.CreateInstance()); DebugReportCallback = ToDispose(VKHelper.CreateDebugReportCallback(Instance)); Surface = ToDispose(VKHelper.CreateSurface(Instance, Window.Handle)); foreach (PhysicalDevice physicalDevice in Instance.EnumeratePhysicalDevices()) { QueueFamilyProperties[] queueFamilyProperties = physicalDevice.GetQueueFamilyProperties(); for (int i = 0; i < queueFamilyProperties.Length; i++) { if (queueFamilyProperties[i].QueueFlags.HasFlag(Queues.Graphics)) { if (GraphicsQueueFamilyIndex == -1) { GraphicsQueueFamilyIndex = i; } if (ComputeQueueFamilyIndex == -1) { ComputeQueueFamilyIndex = i; } if (physicalDevice.GetSurfaceSupportKhr(i, Surface) && VKHelper.GetPresentationSupport(physicalDevice, i)) { PresentQueueFamilyIndex = i; } if (GraphicsQueueFamilyIndex != -1 && ComputeQueueFamilyIndex != -1 && PresentQueueFamilyIndex != -1) { PhysicalDevice = physicalDevice; break; } } } if (PhysicalDevice != null) { break; } } if (PhysicalDevice == null) { throw new InvalidOperationException("No suitable physical device found."); } GenerateDepthStencilFormat(); // Store memory properties of the physical device. MemoryProperties = PhysicalDevice.GetMemoryProperties(); Features = PhysicalDevice.GetFeatures(); Properties = PhysicalDevice.GetProperties(); // Create a logical device. bool sameGraphicsAndPresent = GraphicsQueueFamilyIndex == PresentQueueFamilyIndex; var queueCreateInfos = new DeviceQueueCreateInfo[sameGraphicsAndPresent ? 1 : 2]; queueCreateInfos[0] = new DeviceQueueCreateInfo(GraphicsQueueFamilyIndex, 1, 1.0f); if (!sameGraphicsAndPresent) { queueCreateInfos[1] = new DeviceQueueCreateInfo(PresentQueueFamilyIndex, 1, 1.0f); } var deviceCreateInfo = new DeviceCreateInfo( queueCreateInfos, new[] { Constant.DeviceExtension.KhrSwapchain, Constant.DeviceExtension.KhrMaintenance1 }, Features); Device = PhysicalDevice.CreateDevice(deviceCreateInfo); // Get queue(s). GraphicsQueue = Device.GetQueue(GraphicsQueueFamilyIndex); ComputeQueue = ComputeQueueFamilyIndex == GraphicsQueueFamilyIndex ? GraphicsQueue : Device.GetQueue(ComputeQueueFamilyIndex); PresentQueue = PresentQueueFamilyIndex == GraphicsQueueFamilyIndex ? GraphicsQueue : Device.GetQueue(PresentQueueFamilyIndex); Content = new Content(this); GraphicsCommandPool = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(GraphicsQueueFamilyIndex, CommandPoolCreateFlags.ResetCommandBuffer))); ComputeCommandPool = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(ComputeQueueFamilyIndex))); Graphics = ToDispose(new Graphics(this)); Build(); }
internal static Texture2D FromTextureData(Context ctx, TextureData tex2D) { var stagingBuffer = ctx.Device.CreateBuffer( new BufferCreateInfo(tex2D.Mipmaps[0].Size, BufferUsages.TransferSrc)); MemoryRequirements stagingMemReq = stagingBuffer.GetMemoryRequirements(); int heapIndex = ctx.MemoryProperties.MemoryTypes.IndexOf( stagingMemReq.MemoryTypeBits, MemoryProperties.HostVisible); DeviceMemory stagingMemory = ctx.Device.AllocateMemory( new MemoryAllocateInfo(stagingMemReq.Size, heapIndex)); stagingBuffer.BindMemory(stagingMemory); unsafe { var dest = (byte *)stagingMemory.Map(0, stagingMemReq.Size); var src = (byte *)tex2D.Mipmaps[0].Data.Scan0; for (var i = 0; i < stagingMemReq.Size - 3; i += 4) { *(dest + 2) = *(src++); *(dest + 1) = *(src++); *(dest) = *(src++); *(dest + 3) = *(src++); dest += 4; } } //Interop.Write(ptr, tex2D.Mipmaps[0].Data); stagingMemory.Unmap(); // Setup buffer copy regions for each mip level. var bufferCopyRegions = new BufferImageCopy[tex2D.Mipmaps.Length]; int offset = 0; for (int i = 0; i < bufferCopyRegions.Length; i++) { bufferCopyRegions = new[] { new BufferImageCopy { ImageSubresource = new ImageSubresourceLayers(ImageAspects.Color, i, 0, 1), ImageExtent = tex2D.Mipmaps[0].Extent, BufferOffset = offset } }; offset += tex2D.Mipmaps[i].Size; } // Create optimal tiled target image. Image image = ctx.Device.CreateImage(new ImageCreateInfo { ImageType = ImageType.Image2D, Format = tex2D.Format, MipLevels = tex2D.Mipmaps.Length, ArrayLayers = 1, Samples = SampleCounts.Count1, Tiling = ImageTiling.Optimal, SharingMode = SharingMode.Exclusive, InitialLayout = ImageLayout.Undefined, Extent = tex2D.Mipmaps[0].Extent, Usage = ImageUsages.Sampled | ImageUsages.TransferDst }); MemoryRequirements imageMemReq = image.GetMemoryRequirements(); int imageHeapIndex = ctx.MemoryProperties.MemoryTypes.IndexOf( imageMemReq.MemoryTypeBits, MemoryProperties.DeviceLocal); DeviceMemory memory = ctx.Device.AllocateMemory(new MemoryAllocateInfo(imageMemReq.Size, imageHeapIndex)); image.BindMemory(memory); var subresourceRange = new ImageSubresourceRange(ImageAspects.Color, 0, tex2D.Mipmaps.Length, 0, 1); // Copy the data from staging buffers to device local buffers. CommandBuffer cmdBuffer = ctx.GraphicsCommandPool.AllocateBuffers(new CommandBufferAllocateInfo(CommandBufferLevel.Primary, 1))[0]; cmdBuffer.Begin(new CommandBufferBeginInfo(CommandBufferUsages.OneTimeSubmit)); cmdBuffer.CmdPipelineBarrier(PipelineStages.TopOfPipe, PipelineStages.Transfer, imageMemoryBarriers: new[] { new ImageMemoryBarrier( image, subresourceRange, 0, Accesses.TransferWrite, ImageLayout.Undefined, ImageLayout.TransferDstOptimal) }); cmdBuffer.CmdCopyBufferToImage(stagingBuffer, image, ImageLayout.TransferDstOptimal, bufferCopyRegions); cmdBuffer.CmdPipelineBarrier(PipelineStages.Transfer, PipelineStages.FragmentShader, imageMemoryBarriers: new[] { new ImageMemoryBarrier( image, subresourceRange, Accesses.TransferWrite, Accesses.ShaderRead, ImageLayout.TransferDstOptimal, ImageLayout.ShaderReadOnlyOptimal) }); cmdBuffer.End(); // Submit. Fence fence = ctx.Device.CreateFence(); ctx.GraphicsQueue.Submit(new SubmitInfo(commandBuffers: new[] { cmdBuffer }), fence); fence.Wait(); // Cleanup staging resources. fence.Dispose(); stagingMemory.Dispose(); stagingBuffer.Dispose(); // Create image view. ImageView view = image.CreateView(new ImageViewCreateInfo(tex2D.Format, subresourceRange)); var sampler = VKHelper.CreateSampler(ctx, Filter.Linear, Filter.Linear, SamplerMipmapMode.Linear); return(new Texture2D(ctx, image, memory, view, tex2D.Format, new Vector2I(tex2D.Mipmaps[0].Extent.Width, tex2D.Mipmaps[0].Extent.Height), false)); }