/// <summary> /// Called when the device has been destroyed. /// </summary> private void OnDeviceDestroyed() { this.FreeResources(); this.GraphicsDevice = null; this.ResourceFactory = null; this.Swapchain = null; }
/// <summary> /// Called when the graphics device has been created. /// </summary> /// <param name="device">The graphics device.</param> /// <param name="factory">The resource factory.</param> /// <param name="swapchain">The swapchain.</param> private void OnGraphicsDeviceCreated(GraphicsDevice device, ResourceFactory factory, Swapchain swapchain) { this.GraphicsDevice = device; this.ResourceFactory = factory; this.Swapchain = swapchain; this.CreateResources(factory); }
private unsafe void DestroySwapchain() { if (swapChain == Swapchain.Null) { return; } // stop our presenter thread if (presenterThread != null) { runPresenter = false; presentWaiter.Set(); presenterThread.Join(); } GraphicsDevice.NativeDevice.WaitIdle(); CommandList.ResetAllPools(); backbuffer.OnDestroyed(); foreach (var swapchainImage in swapchainImages) { GraphicsDevice.NativeDevice.DestroyImageView(swapchainImage.NativeColorAttachmentView); } swapchainImages = null; GraphicsDevice.NativeDevice.DestroySwapchain(swapChain); swapChain = Swapchain.Null; }
private unsafe void PresenterThread() { Swapchain swapChainCopy = swapChain; uint currentBufferIndexCopy = 0; PresentInfo presentInfo = new PresentInfo { StructureType = StructureType.PresentInfo, SwapchainCount = 1, Swapchains = new IntPtr(&swapChainCopy), ImageIndices = new IntPtr(¤tBufferIndexCopy), WaitSemaphoreCount = 0 }; while (runPresenter) { // wait until we have a frame to present presentWaiter.Wait(); currentBufferIndexCopy = presentingIndex; // are we still OK to present? if (runPresenter == false) { return; } using (GraphicsDevice.QueueLock.WriteLock()) { GraphicsDevice.NativeCommandQueue.Present(ref presentInfo); } presentWaiter.Reset(); } }
public override void ViewDidLoad() { base.ViewDidLoad(); SwapchainSource ss = SwapchainSource.CreateUIView(this.View.Handle); SwapchainDescription scd = new SwapchainDescription( ss, (uint)View.Frame.Width, (uint)View.Frame.Height, PixelFormat.R32_Float, false); if (_backend == GraphicsBackend.Metal) { _gd = GraphicsDevice.CreateMetal(_options); _sc = _gd.ResourceFactory.CreateSwapchain(ref scd); } else if (_backend == GraphicsBackend.OpenGLES) { _gd = GraphicsDevice.CreateOpenGLES(_options, scd); _sc = _gd.MainSwapchain; } else if (_backend == GraphicsBackend.Vulkan) { throw new NotImplementedException(); } GraphicsDeviceCreated?.Invoke(_gd, _gd.ResourceFactory, _sc); _viewLoaded = true; }
protected void OnGraphicsDeviceCreated(GraphicsDevice gd, ResourceFactory factory, Swapchain sc) { GraphicsDevice = gd; Factory = factory; Swapchain = sc; CreateResources(); Chunk.CreateResources(this); FastNoise noise = new FastNoise(); noise.SetNoiseType(FastNoise.NoiseType.Simplex); int size = 256; int delta = 10; int[,] heightMap = new int[size, size]; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { heightMap[x, y] = (int)(noise.GetNoise(x, y) * delta); } } for (int x = 0; x < size; x += Chunk.WIDTH) { for (int y = 0; y < size; y += Chunk.WIDTH) { var _chunk = new Chunk(x, y, heightMap, new Random()); Chunks.Add(new Tuple <int, int>(x, y), _chunk); } } }
/// <summary> /// Configure the render for rendering. /// </summary> public override void ConfigureRendering() { base.ConfigureRendering(); // - Initialize the swap chain Swapchain.Initialize(PhysicalDevice.DrawingSurface, TargetSurface.SurfaceSize); // - Initialzie the swapchain images Swapchain.CreateImageViews(); // - Configure the default render pass DefaultRenderPass.Initialize((Format)Swapchain.CurrentFormat.Format); // - Load shaders ShaderManager.CreateShaders(); // - Gets default shaders var defaultShader = ShaderManager[typeof(DefaultShader)] as VKShaderInstance; Pipeline.Shader = defaultShader; // - Initialize pipeline Pipeline.Initialize(TargetSurface.SurfaceSize); // - Build swapchain framebuffers Swapchain.CreateFrameBuffers(DefaultRenderPass); for (int i = 0; i < Swapchain.Images.Count(); ++i) { ImagesInFlight.Add(null); } }
/// <summary> /// Dispose(bool disposing) executes in two distinct scenarios. /// If disposing equals <see cref="true"/>, the method has been called directly /// or indirectly by a user's code. Managed and unmanaged resources /// can be disposed. /// If disposing equals <see cref="false"/>, the method has been called by the /// runtime from inside the finalizer and you should not reference /// other objects. Only unmanaged resources can be disposed. /// </summary> /// <param name="disposing"><see cref="True"/> if called from user's code.</param> protected override void Dispose(bool disposing) { // Check to see if Dispose has already been called. if (!Disposed) { // - Destroy all images foreach (var img in Images) { img?.Destroy(); } foreach (var img in ImageViews) { img?.Destroy(); } foreach (var fb in VideoBuffers) { fb?.Handler.Destroy(); } images = new Image[0]; imageViews = new ImageView[0]; videoBuffers = new Framebuffer[0]; // - Destroy swap chain Handle?.Dispose(); Handle = null; // Note disposing has been done. Disposed = true; } }
/// <summary> /// This call configure the graphic library for the new device instance. /// </summary> public override void InvalidateDevice() { base.InvalidateDevice(); // - Wait the GPU (we must operate only when GPU is idle) GraphicDevice.Handle.WaitIdle(); // - Dispose render pass DefaultRenderPass.Dispose(); // - Dispose the pipeline Pipeline.Dispose(); // - Dipose current swapchain Swapchain.Dispose(); // - Dispose current VK surface DrawingSurface.Dispose(); // - Dispose vertex and index managers VertexManager.Dispose(); IndexManager.Dispose(); // - Release all VK shaders ShaderManager.Dispose(); for (int i = 0; i < MaxFrameInFlight; ++i) { if (CommandBuffers[i] != null) { foreach (var buffer in CommandBuffers[i]) { buffer.Reset(); } Commands[i].FreeCommandBuffers(CommandBuffers[i]); } } foreach (Fence fence in InFlightFences) { fence.Destroy(); } foreach (Semaphore sem in ImageAvailableSemaphores) { sem.Destroy(); } foreach (Semaphore sem in RenderFinishedSemaphores) { sem.Destroy(); } // - Dispose device GraphicDevice.Dispose(); // - Initialize device Initialize(); // - Reconfigure the renderer ConfigureRendering(); }
public MirrorTextureManager(GraphicsDevice gd, VRContext vr, Swapchain sc) { _Ext_GD = gd; _Ext_VR = vr; _Ext_SC = sc; _Commands = gd.ResourceFactory.CreateCommandList(); }
/// <summary> /// Create a window /// </summary> /// <param name="title">title for the window</param> /// <param name="x">x position</param> /// <param name="y">y position</param> /// <param name="width">width of the window</param> /// <param name="height">height of the window</param> /// <param name="flags">flags for window</param> public Window( string title, int x, int y, int width, int height, WindowFlags flags = ( WindowFlags.AllowHighDpi | WindowFlags.Shown ) ) : base( Engine.Instance.GetModule <GraphicsModule>().GraphicsService.PrimaryDevice, Convert.ToUInt32(width), Convert.ToUInt32(height) ) { Windows.Add(this); _graphicsModule = Engine.Instance.GetModule <GraphicsModule>(); _nativeWindow = new NativeWindow( _graphicsModule.GraphicsService, title, x, y, width, height, (SDL_WindowFlags)flags ); _swapchain = new Swapchain( _graphicsModule.GraphicsService.PrimaryDevice, _nativeWindow ); _fence = new Fence(_graphicsModule.GraphicsService.PrimaryDevice); }
public Renderer(Sdl2Window aWindow) { mClock.Start(); mPreviousElapsed = mClock.Elapsed.TotalSeconds; mWindow = aWindow; mWindow.Resized += () => { mWindowResized = true; }; GraphicsDeviceOptions options = new GraphicsDeviceOptions( debug: false, swapchainDepthFormat: PixelFormat.R16_UNorm, syncToVerticalBlank: true, resourceBindingModel: ResourceBindingModel.Improved, preferDepthRangeZeroToOne: true, preferStandardClipSpaceYDirection: true); mGraphicsDevice = VeldridStartup.CreateGraphicsDevice(aWindow, options); mSwapchain = mGraphicsDevice.MainSwapchain; mFactory = mGraphicsDevice.ResourceFactory; mImguiRenderer = new ImGuiRenderer(mGraphicsDevice, mSwapchain.Framebuffer.OutputDescription, aWindow.Width, aWindow.Height); }
public override Swapchain CreateSwapchain(ref SwapchainDescription description) { Swapchain sc = Factory.CreateSwapchain(ref description); DisposeCollector.Add(sc); return(sc); }
/// <summary> /// Implement IDisposable. /// </summary> protected override void Dispose(bool disposing) { base.Dispose(disposing); GraphicDevice.Handle.WaitForFences(InFlightFences.ToArray(), true, UInt64.MaxValue); // - Wait the GPU (we must operate only when GPU is idle) GraphicDevice.Handle.WaitIdle(); // - Dispose render pass DefaultRenderPass.Dispose(); // - Dispose the pipeline Pipeline.Dispose(); // - Dipose current swapchain Swapchain.Dispose(); // - Dispose vertex and index managers VertexManager.Dispose(); IndexManager.Dispose(); // - Release all VK shaders ShaderManager.Dispose(); for (int i = 0; i < MaxFrameInFlight; ++i) { if (CommandBuffers[i] != null) { foreach (var buffer in CommandBuffers[i]) { buffer.Reset(); } } } foreach (CommandPool pool in Commands) { pool?.Destroy(); } foreach (Fence fence in InFlightFences) { fence?.Destroy(); } foreach (Semaphore sem in ImageAvailableSemaphores) { sem?.Destroy(); } foreach (Semaphore sem in RenderFinishedSemaphores) { sem?.Destroy(); } // - Dispose device GraphicDevice.Dispose(); // - Dispose vulkan Library.Dispose(); }
protected override void SwapBuffersCore(Swapchain swapchain) { lock (_immediateContextLock) { D3D11Swapchain d3d11SC = Util.AssertSubtype <Swapchain, D3D11Swapchain>(swapchain); d3d11SC.DxgiSwapChain.Present(d3d11SC.SyncInterval, PresentFlags.None); } }
public void OnGraphicsDeviceCreated(GraphicsDevice gd, ResourceFactory factory, Swapchain sc) { GraphicsDevice = gd; ResourceFactory = factory; MainSwapchain = sc; CreateResources(factory); CreateSwapchainResources(factory); }
private void TearDown() { device.WaitIdle(); renderFinishedSemaphore.Dispose(); renderFinishedSemaphore = null; imageAvailableSemaphore.Dispose(); imageAvailableSemaphore = null; vertexBufferMemory.Free(); vertexBufferMemory = null; vertexBuffer.Dispose(); vertexBuffer = null; commandPool.Dispose(); commandPool = null; foreach (var frameBuffer in frameBuffers) { frameBuffer.Dispose(); } frameBuffers = null; fragShader.Dispose(); fragShader = null; vertShader.Dispose(); vertShader = null; pipeline.Dispose(); pipeline = null; pipelineLayout.Dispose(); pipelineLayout = null; foreach (var imageView in swapChainImageViews) { imageView.Dispose(); } swapChainImageViews = null; renderPass.Dispose(); renderPass = null; swapChain.Dispose(); swapChain = null; device.Dispose(); device = null; surface.Dispose(); surface = null; instance.Dispose(); instance = null; }
private void TearDown() { device.WaitIdle(); this.renderFinishedSemaphore.Dispose(); this.renderFinishedSemaphore = null; this.imageAvailableSemaphore.Dispose(); this.imageAvailableSemaphore = null; this.device.FreeMemory(this.vertexBufferMemory); this.vertexBufferMemory = null; this.vertexBuffer.Dispose(); this.vertexBuffer = null; this.commandPool.Dispose(); this.commandPool = null; foreach (var frameBuffer in this.frameBuffers) { frameBuffer.Dispose(); } this.frameBuffers = null; this.fragShader.Dispose(); this.fragShader = null; this.vertShader.Dispose(); this.vertShader = null; this.pipeline.Dispose(); this.pipeline = null; this.pipelineLayout.Dispose(); this.pipelineLayout = null; foreach (var imageView in this.swapChainImageViews) { imageView.Dispose(); } this.swapChainImageViews = null; this.renderPass.Dispose(); this.renderPass = null; this.swapChain.Dispose(); this.swapChain = null; this.device.Dispose(); this.device = null; this.surface.Dispose(); this.surface = null; this.instance.Dispose(); this.instance = null; }
protected override void Dispose(bool disposing) { if (disposing) { Swapchain.Dispose(); } base.Dispose(disposing); }
private void InitializeGraphicsBackend() { switch (Backend) { case GraphicsBackend.Metal: GraphicsDevice = GraphicsDevice.CreateMetal(GraphicsDeviceOptions); break; case GraphicsBackend.Vulkan: GraphicsDevice = GraphicsDevice.CreateVulkan(GraphicsDeviceOptions); break; case GraphicsBackend.Direct3D11: GraphicsDevice = GraphicsDevice.CreateD3D11(GraphicsDeviceOptions); break; case GraphicsBackend.OpenGL: Handler.UpdateWindowInfo(OpenTKGraphicsMode); var glInfo = new OpenGLPlatformInfo( VeldridGL.GetGLContextHandle(), VeldridGL.GetProcAddress, (c) => OpenTKGraphicsContext.MakeCurrent(Handler.WindowInfo), VeldridGL.GetCurrentContext, VeldridGL.ClearCurrentContext, VeldridGL.DeleteContext, VeldridGL.SwapBuffers, VeldridGL.SetVSync, VeldridGL.SetSwapchainFramebuffer, Handler.ResizeSwapchain); GraphicsDevice = GraphicsDevice.CreateOpenGL( GraphicsDeviceOptions, glInfo, (uint)RenderWidth, (uint)RenderHeight); break; default: string message; if (!Enum.IsDefined(typeof(GraphicsBackend), Backend)) { message = "Unrecognized backend!"; } else { message = "Specified backend not supported on this platform!"; } throw new ArgumentException(message); } Swapchain = Handler.CreateSwapchain(); OnVeldridInitialized(EventArgs.Empty); }
/// <summary> /// 在设备创建完成后初始化和创建资源 /// </summary> /// <param name="gd"></param> /// <param name="factory"></param> /// <param name="sc"></param> public void OnGraphicsDeviceCreated(GraphicsDevice gd, ResourceFactory factory, Swapchain sc) { GraphicsDevice = gd; ResourceFactory = factory; MainSwapchain = sc; CreateResources(factory); CreateSwapchainResources(factory); //_controller = new ImGuiController(this.GraphicsDevice, this.GraphicsDevice.MainSwapchain.Framebuffer.OutputDescription, (int)this.Window.Width, (int)this.Window.Height); }
private void SetupSwapChain() { uint width, height; Swapchain.Create(&width, &height, Settings.VSync); this.width = width; this.height = height; }
public unsafe Swapchain[] CreateSharedSwapchains(SwapchainCreateInfo[] createInfos, AllocationCallbacks allocator) { var swapchains = new Swapchain[createInfos.Length]; fixed (SwapchainCreateInfo* __createInfos__ = &createInfos[0]) fixed (Swapchain* __swapchains__ = &swapchains[0]) { vkCreateSharedSwapchainsKHR(this, (uint)createInfos.Length, __createInfos__, &allocator, __swapchains__).CheckError(); } return swapchains; }
public unsafe Swapchain[] CreateSharedSwapchains(SwapchainCreateInfo[] createInfos, AllocationCallbacks allocator) { var swapchains = new Swapchain[createInfos.Length]; fixed(SwapchainCreateInfo *__createInfos__ = &createInfos[0]) fixed(Swapchain * __swapchains__ = &swapchains[0]) { vkCreateSharedSwapchainsKHR(this, (uint)createInfos.Length, __createInfos__, &allocator, __swapchains__).CheckError(); } return(swapchains); }
public void InitSwapchain() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Swapchain.InitSurface(WindowInstance, Window); } else { throw new NotImplementedException(); } }
public void Initialize(IVulkanAppHost host) { Host = host; #if DEBUG const bool debug = true; #else const bool debug = false; #endif _initializingPermanent = true; // Calling ToDispose here registers the resource to be automatically disposed on exit. Instance = ToDispose(CreateInstance(debug)); DebugReportCallback = ToDispose(CreateDebugReportCallback(debug)); Surface = ToDispose(CreateSurface()); Context = ToDispose(new VulkanContext(Instance, Surface, Host.Platform)); Content = ToDispose(new ContentManager(Host, Context, "Content")); ImageAvailableSemaphore = ToDispose(Context.Device.CreateSemaphore()); RenderingFinishedSemaphore = ToDispose(Context.Device.CreateSemaphore()); if (host.Platform == Platform.MacOS) { //Setup MoltenVK specific device configuration. MVKDeviceConfiguration deviceConfig = Context.Device.GetMVKDeviceConfiguration(); deviceConfig.DebugMode = debug; deviceConfig.PerformanceTracking = debug; deviceConfig.PerformanceLoggingFrameCount = debug ? 300 : 0; Context.Device.SetMVKDeviceConfiguration(deviceConfig); } _initializingPermanent = false; // Calling ToDispose here registers the resource to be automatically disposed on events // such as window resize. Swapchain = ToDispose(CreateSwapchain()); // Acquire underlying images of the freshly created swapchain. SwapchainImages = Swapchain.GetImages(); // Create a command buffer for each swapchain image. CommandBuffers = Context.GraphicsCommandPool.AllocateBuffers( new CommandBufferAllocateInfo(CommandBufferLevel.Primary, SwapchainImages.Length)); // Create a fence for each commandbuffer so that we can wait before using it again _initializingPermanent = true; //We need our fences to be there permanently SubmitFences = new Fence[SwapchainImages.Length]; for (int i = 0; i < SubmitFences.Length; i++) { ToDispose(SubmitFences[i] = Context.Device.CreateFence(new FenceCreateInfo(FenceCreateFlags.Signaled))); } // Allow concrete samples to initialize their resources. InitializePermanent(); _initializingPermanent = false; InitializeFrame(); // Record commands for execution by Vulkan. RecordCommandBuffers(); }
public override void ViewDidLoad() { base.ViewDidLoad(); View.BackgroundColor = UIColor.SystemPinkColor; // device init GraphicsDeviceOptions options = new GraphicsDeviceOptions(false, null, false, ResourceBindingModel.Improved); #if DEBUG options.Debug = true; #endif SwapchainSource ss = SwapchainSource.CreateUIView(this.View.Handle); SwapchainDescription scd = new SwapchainDescription( ss, width, height, PixelFormat.R32_Float, false); graphicsDevice = GraphicsDevice.CreateMetal(options); swapchain = graphicsDevice.ResourceFactory.CreateSwapchain(ref scd); factory = graphicsDevice.ResourceFactory; // resource init CreateSizeDependentResources(); VertexPosition[] quadVertices = { new VertexPosition(new Vector3(-1, 1, 0)), new VertexPosition(new Vector3(1, 1, 0)), new VertexPosition(new Vector3(-1, -1, 0)), new VertexPosition(new Vector3(1, -1, 0)) }; uint[] quadIndices = new uint[] { 0, 1, 2, 1, 3, 2 }; vertexBuffer = factory.CreateBuffer(new BufferDescription(4 * VertexPosition.SizeInBytes, BufferUsage.VertexBuffer)); indexBuffer = factory.CreateBuffer(new BufferDescription(6 * sizeof(uint), BufferUsage.IndexBuffer)); graphicsDevice.UpdateBuffer(vertexBuffer, 0, quadVertices); graphicsDevice.UpdateBuffer(indexBuffer, 0, quadIndices); commandList = factory.CreateCommandList(); viewLoaded = true; displayLink = CADisplayLink.Create(Render); displayLink.PreferredFramesPerSecond = 60; displayLink.AddToRunLoop(NSRunLoop.Main, NSRunLoop.NSDefaultRunLoopMode); }
private void InitializeGraphicsBackend(InitializeEventArgs e) { switch (Backend) { case GraphicsBackend.Metal: GraphicsDevice = GraphicsDevice.CreateMetal(GraphicsDeviceOptions); break; case GraphicsBackend.Direct3D11: GraphicsDevice = GraphicsDevice.CreateD3D11(GraphicsDeviceOptions); break; case GraphicsBackend.Vulkan: GraphicsDevice = GraphicsDevice.CreateVulkan(GraphicsDeviceOptions); break; case GraphicsBackend.OpenGL: GraphicsDevice = GraphicsDevice.CreateOpenGL( GraphicsDeviceOptions, new OpenGLPlatformInfo( OpenGL.OpenGLContextHandle, OpenGL.GetProcAddress, OpenGL.MakeCurrent, OpenGL.GetCurrentContext, OpenGL.ClearCurrentContext, OpenGL.DeleteContext, OpenGL.SwapBuffers, OpenGL.SetSyncToVerticalBlank, OpenGL.SetSwapchainFramebuffer, OpenGL.ResizeSwapchain), (uint)e.Width, (uint)e.Height); break; default: string message; if (!Enum.IsDefined(typeof(GraphicsBackend), Backend)) { message = "Unrecognized backend!"; } else { message = "Specified backend not supported on this platform!"; } throw new ArgumentException(message); } Swapchain = Handler.CreateSwapchain(); OnVeldridInitialized(e); }
protected virtual void CreateSwapchain() { var dpiScale = GetDpiScale(); var width = (uint)(ActualWidth < 0 ? 0 : Math.Ceiling(ActualWidth * dpiScale)); var height = (uint)(ActualHeight < 0 ? 0 : Math.Ceiling(ActualHeight * dpiScale)); var mainModule = typeof(VeldridComponent).Module; var hinstance = Marshal.GetHINSTANCE(mainModule); var win32Source = SwapchainSource.CreateWin32(Hwnd, hinstance); var scDesc = new SwapchainDescription(win32Source, width, height, PixelFormat.R32_Float, true); _sc = _gd.ResourceFactory.CreateSwapchain(scDesc); }
public override void ViewDidLoad() { base.ViewDidLoad(); // device init GraphicsDeviceOptions options = new GraphicsDeviceOptions(false, null, false, ResourceBindingModel.Improved); #if DEBUG options.Debug = true; #endif SwapchainSource ss = SwapchainSource.CreateNSView(this.View.Handle); SwapchainDescription scd = new SwapchainDescription( ss, width, height, PixelFormat.R32_Float, false); graphicsDevice = GraphicsDevice.CreateMetal(options); swapchain = graphicsDevice.ResourceFactory.CreateSwapchain(ref scd); factory = graphicsDevice.ResourceFactory; // resource init CreateSizeDependentResources(); VertexPosition[] quadVertices = { new VertexPosition(new Vector3(-1, 1, 0)), new VertexPosition(new Vector3(1, 1, 0)), new VertexPosition(new Vector3(-1, -1, 0)), new VertexPosition(new Vector3(1, -1, 0)) }; uint[] quadIndices = new uint[] { 0, 1, 2, 1, 3, 2 }; vertexBuffer = factory.CreateBuffer(new BufferDescription(4 * VertexPosition.SizeInBytes, BufferUsage.VertexBuffer)); indexBuffer = factory.CreateBuffer(new BufferDescription(6 * sizeof(uint), BufferUsage.IndexBuffer)); graphicsDevice.UpdateBuffer(vertexBuffer, 0, quadVertices); graphicsDevice.UpdateBuffer(indexBuffer, 0, quadIndices); commandList = factory.CreateCommandList(); viewLoaded = true; displayTimer = NSTimer.CreateRepeatingTimer(60.0 / 1000.0, Render); displayTimer.Fire(); }
public unsafe Image[] GetSwapchainImages(Swapchain swapchain) { uint count = 0; GetSwapchainImages(swapchain, ref count, null); var result = new Image[count]; if (count > 0) { fixed (Image* resultPtr = &result[0]) GetSwapchainImages(swapchain, ref count, resultPtr); } return result; }
/// <summary> /// 在设备创建完成后初始化和创建资源 /// </summary> /// <param name="gd"></param> /// <param name="factory"></param> /// <param name="sc"></param> public void OnGraphicsDeviceCreated(GraphicsDevice gd, ResourceFactory factory, Swapchain sc) { //临时创建UI var mainUi = new MainUIRender(gd, Window.Handle, Window.Width, Window.Height); renders.Add(mainUi); _browHost = mainUi; GraphicsDevice = gd; ResourceFactory = factory; MainSwapchain = sc; CreateResources(factory); CreateSwapchainResources(factory); _controller = new ImGuiRenderer(this.GraphicsDevice, this.GraphicsDevice.MainSwapchain.Framebuffer.OutputDescription, (int)this.Window.Width, (int)this.Window.Height); }
protected virtual void CreateSwapchain() { // surface format var surfaceFormats = physicalDevice.GetSurfaceFormats(surface); if (surfaceFormats.Length == 1 && surfaceFormats[0].Format == Format.Undefined) { backBufferFormat = Format.B8G8R8A8UNorm; } else { backBufferFormat = surfaceFormats[0].Format; } SurfaceCapabilities surfaceCapabilities; physicalDevice.GetSurfaceCapabilities(surface, out surfaceCapabilities); // Buffer count uint desiredImageCount = surfaceCapabilities.MinImageCount + 1; if (surfaceCapabilities.MaxImageCount > 0 && desiredImageCount > surfaceCapabilities.MaxImageCount) { desiredImageCount = surfaceCapabilities.MaxImageCount; } // Transform SurfaceTransformFlags preTransform; if ((surfaceCapabilities.SupportedTransforms & SurfaceTransformFlags.Identity) != 0) { preTransform = SurfaceTransformFlags.Identity; } else { preTransform = surfaceCapabilities.CurrentTransform; } // Present mode var presentModes = physicalDevice.GetSurfacePresentModes(surface); var swapChainPresentMode = PresentMode.Fifo; if (presentModes.Contains(PresentMode.Mailbox)) swapChainPresentMode = PresentMode.Mailbox; else if (presentModes.Contains(PresentMode.Immediate)) swapChainPresentMode = PresentMode.Immediate; // Create swapchain var swapchainCreateInfo = new SwapchainCreateInfo { StructureType = StructureType.SwapchainCreateInfo, Surface = surface, ImageSharingMode = SharingMode.Exclusive, ImageExtent = new Extent2D((uint)form.ClientSize.Width, (uint)form.ClientSize.Height), ImageArrayLayers = 1, ImageFormat = backBufferFormat, ImageColorSpace = ColorSpace.SRgbNonlinear, ImageUsage = ImageUsageFlags.ColorAttachment, PresentMode = swapChainPresentMode, CompositeAlpha = CompositeAlphaFlags.Opaque, MinImageCount = desiredImageCount, PreTransform = preTransform, Clipped = true // OldSwapchain = }; swapchain = device.CreateSwapchain(ref swapchainCreateInfo); // Initialize swapchain image layout backBuffers = device.GetSwapchainImages(swapchain); foreach (var image in backBuffers) { SetImageLayout(image, ImageAspectFlags.Color, ImageLayout.Undefined, ImageLayout.PresentSource); } Flush(); }
private unsafe void CreateSwapChain() { var formats = new[] { PixelFormat.B8G8R8A8_UNorm_SRgb, PixelFormat.R8G8B8A8_UNorm_SRgb, PixelFormat.B8G8R8A8_UNorm, PixelFormat.R8G8B8A8_UNorm }; foreach (var format in formats) { var nativeFromat = VulkanConvertExtensions.ConvertPixelFormat(format); FormatProperties formatProperties; GraphicsDevice.NativePhysicalDevice.GetFormatProperties(nativeFromat, out formatProperties); if ((formatProperties.OptimalTilingFeatures & FormatFeatureFlags.ColorAttachment) != 0) { Description.BackBufferFormat = format; break; } } // Queue // TODO VULKAN: Queue family is needed when creating the Device, so here we can just do a sanity check? var queueNodeIndex = GraphicsDevice.NativePhysicalDevice.QueueFamilyProperties. Where((properties, index) => (properties.QueueFlags & QueueFlags.Graphics) != 0 && GraphicsDevice.NativePhysicalDevice.GetSurfaceSupport((uint)index, surface)). Select((properties, index) => index).First(); // Surface format var backBufferFormat = VulkanConvertExtensions.ConvertPixelFormat(Description.BackBufferFormat); var surfaceFormats = GraphicsDevice.NativePhysicalDevice.GetSurfaceFormats(surface); if ((surfaceFormats.Length != 1 || surfaceFormats[0].Format != Format.Undefined) && !surfaceFormats.Any(x => x.Format == backBufferFormat)) { backBufferFormat = surfaceFormats[0].Format; } // Create swapchain SurfaceCapabilities surfaceCapabilities; GraphicsDevice.NativePhysicalDevice.GetSurfaceCapabilities(surface, out surfaceCapabilities); // Buffer count uint desiredImageCount = Math.Max(surfaceCapabilities.MinImageCount, 2); if (surfaceCapabilities.MaxImageCount > 0 && desiredImageCount > surfaceCapabilities.MaxImageCount) { desiredImageCount = surfaceCapabilities.MaxImageCount; } // Transform SurfaceTransformFlags preTransform; if ((surfaceCapabilities.SupportedTransforms & SurfaceTransformFlags.Identity) != 0) { preTransform = SurfaceTransformFlags.Identity; } else { preTransform = surfaceCapabilities.CurrentTransform; } // Find present mode var presentModes = GraphicsDevice.NativePhysicalDevice.GetSurfacePresentModes(surface); var swapChainPresentMode = PresentMode.Fifo; // Always supported foreach (var presentMode in presentModes) { // TODO VULKAN: Handle PresentInterval.Two if (Description.PresentationInterval == PresentInterval.Immediate) { // Prefer mailbox to immediate if (presentMode == PresentMode.Immediate) { swapChainPresentMode = PresentMode.Immediate; } else if (presentMode == PresentMode.Mailbox) { swapChainPresentMode = PresentMode.Mailbox; break; } } } // Create swapchain var swapchainCreateInfo = new SwapchainCreateInfo { StructureType = StructureType.SwapchainCreateInfo, Surface = surface, ImageArrayLayers = 1, ImageSharingMode = SharingMode.Exclusive, ImageExtent = new Extent2D((uint)Description.BackBufferWidth, (uint)Description.BackBufferHeight), ImageFormat = backBufferFormat, ImageColorSpace = Description.ColorSpace == ColorSpace.Gamma ? SharpVulkan.ColorSpace.SRgbNonlinear : 0, ImageUsage = ImageUsageFlags.ColorAttachment | (surfaceCapabilities.SupportedUsageFlags & ImageUsageFlags.TransferSource), // TODO VULKAN: Use off-screen buffer to emulate PresentMode = swapChainPresentMode, CompositeAlpha = CompositeAlphaFlags.Opaque, MinImageCount = desiredImageCount, PreTransform = preTransform, OldSwapchain = swapChain, Clipped = true }; var newSwapChain = GraphicsDevice.NativeDevice.CreateSwapchain(ref swapchainCreateInfo); DestroySwapchain(); swapChain = newSwapChain; CreateBackBuffers(); }
private unsafe void DestroySwapchain() { if (swapChain == Swapchain.Null) return; GraphicsDevice.NativeDevice.WaitIdle(); backbuffer.OnDestroyed(); foreach (var swapchainImage in swapchainImages) { GraphicsDevice.NativeDevice.DestroyImageView(swapchainImage.NativeColorAttachmentView); } swapchainImages = null; GraphicsDevice.NativeDevice.DestroySwapchain(swapChain); swapChain = Swapchain.Null; }
internal static unsafe extern Result vkAcquireNextImageKHR(Device device, Swapchain swapchain, ulong timeout, Semaphore semaphore, Fence fence, uint* imageIndex);
public unsafe void DestroySwapchain(Swapchain swapchain, AllocationCallbacks* allocator = null) { vkDestroySwapchainKHR(this, swapchain, allocator); }
internal static unsafe extern Result vkCreateSharedSwapchainsKHR(Device device, uint swapchainCount, SwapchainCreateInfo* createInfos, AllocationCallbacks* allocator, Swapchain* swapchains);
internal static unsafe extern Result vkCreateSwapchainKHR(Device device, SwapchainCreateInfo* createInfo, AllocationCallbacks* allocator, Swapchain* swapchain);
public unsafe uint AcquireNextImage(Swapchain swapchain, ulong timeout, Semaphore semaphore, Fence fence) { uint imageIndex; vkAcquireNextImageKHR(this, swapchain, timeout, semaphore, fence, &imageIndex).CheckError(); return imageIndex; }
internal static unsafe extern void vkDestroySwapchainKHR(Device device, Swapchain swapchain, AllocationCallbacks* allocator);
internal unsafe void GetSwapchainImages(Swapchain swapchain, ref uint swapchainImageCount, Image* swapchainImages) { fixed (uint* __swapchainImageCount__ = &swapchainImageCount) { vkGetSwapchainImagesKHR(this, swapchain, __swapchainImageCount__, swapchainImages).CheckError(); } }
internal static unsafe extern Result vkGetSwapchainImagesKHR(Device device, Swapchain swapchain, uint* swapchainImageCount, Image* swapchainImages);