Conversation
Previously, DenyShaderResource was set if TextureUsages lacked Sampled. Now, it is set only when TextureUsages includes DepthStencilAttachment but not Sampled, restricting denial to unsampled depth-stencil attachments.
Updated Avalonia to 12.1.1, Slangc.NET to 2026.14.1, and Uno.WinUI to 6.6.184 to keep dependencies current.
Introduce CanTransition to DXTexture to indicate if a texture supports transitions. Update constructors and related classes to set this property. DXCommandBuffer.TransitionImpl now checks CanTransition before transitioning. Adjust DXGraphicsContext and DXHeap to pass CanTransition when creating textures.
The textures array now initializes each Texture with an additional boolean argument (true), reflecting a change in the Texture class constructor. This likely enables a new behavior or flag during texture initialization.
Added a ComPtr<ID3D11Query> to Surface and created the query in the constructor. Wrapped resource copy with Begin/End on the query and replaced DeviceContext.Flush() with a polling loop using GetData to ensure copy completion before proceeding.
Introduce ComPtr<ID3D11Query> to Surface for GPU synchronization. Replace DeviceContext.Flush with Begin/End query and GetData polling. Ensure proper disposal of Query in Surface.Dispose. Align WinUI implementation with GetData polling logic.
Replaced synchronous Dispatcher.Invoke/Invoke with asynchronous Dispatcher.InvokeAsync/InvokeAsync using DispatcherPriority.Render to enhance UI responsiveness. Added System.Windows.Threading import for DispatcherPriority support.
Updated IZenithView.UI to invoke actions with the default dispatcher priority by removing the DispatcherPriority.Render argument from Dispatcher.InvokeAsync. This simplifies priority management for UI actions.
Upgraded the SkiaSharp NuGet package from 4.150.1 to 4.151.0 in Directory.Packages.props. No other package versions were changed; only minor formatting adjustments were made.
Introduced Zenith.NET.Extensions.Skia namespace with SkiaSharp integration. Added Extensions.cs for GraphicsContext extension to create SKTexture with GRContext management. Implemented SKTexture and SKTextureDesc types for texture handling; methods are not yet implemented.
Implement GetNativeObject in graphics API wrappers to return native handles or pointers based on NativeObjectType. Expand NativeObjectType enum to cover all supported native objects for DirectX 12, Metal, and Vulkan, enabling type-safe access to underlying resources.
The GetNativeObject method in MTLTextureView now returns 0 for all NativeObjectType values, instead of returning Texture.NativePtr for MTLTexture and default for others.
Refactors Skia integration in Zenith.NET for improved thread safety and extensibility: - Replaces GRContext dictionary with thread-safe SKRenderer management using reference counting. - Adds SKFormats.cs for mapping Zenith.NET formats to SkiaSharp, DirectX12, and Vulkan equivalents. - Implements SKRenderer for backend context creation and resource management across DirectX12, Metal, and Vulkan. - Refactors SKTexture to use SKRenderer, improving resource cleanup and API abstraction. - Ensures robust, multi-API rendering with proper resource lifecycle handling.
Added SkiaBoard project to Experiments, including project file and source code. Implemented App.cs for window/input/rendering setup with Silk.NET and Zenith.NET, integrating SkiaSharp for drawing. Board.cs provides drawing board features: brush/eraser, color palette, undo/redo, clear, and brush size adjustment. CocoaHelper.cs enables Metal layer interop on macOS. Updated Program.cs to launch SkiaBoard and Zenith.NET.slnx to include the new project.
The solution file was updated to include a Byte Order Mark (BOM) at the beginning. No other modifications to the solution structure or project references were made.
- Changed Gallery, GalleryResources, and scene classes from sealed to non-sealed for inheritance support. - Moved scene classes to SkiaGallery.Scenes namespace. - Made GalleryResources.CreateText static and updated all usages. - Improved code formatting and consistency. - Added missing using directives in App.cs and Gallery.cs. - Added UTF-8 BOM to project and source files.
- Added new static SKColor fields to GalleryPalette: Navigation, Ink, Muted, Line, Accent, Coral, Blue, and Amber. - Modified SKTexture constructor to set Usages to only ColorAttachment and TransferSrc. - Removed Usages field from SKTextureDesc struct.
Add an interactive vector whiteboard that demonstrates the minimal Skia GPU interop path: GraphicsContext, swap chain, GPU-backed SKTexture.Render, copy, present. Finished strokes are baked into an SKPicture so each frame only redraws the in-progress stroke. The eraser sweeps a segment between frames and splits strokes into surviving fragments instead of deleting them outright.
Added required using directives to multiple files. Simplified point addition in Board.cs with the null-conditional operator. Refactored EnsureLayout by defining 'top' and 'bottom' as constants at the method's start.
Refactored App.cs to move event subscriptions into the Run method using inline lambdas. Inlined CreateTexture and DrawBoard logic. Simplified DPI scaling and logical size calculations. Handled texture recreation and swap chain resizing in window.Resize event. Removed nullable assertion in Board.cs and improved null checks in Stroke.cs for eraser operations.
Added TextureUsages.Sampled and TextureUsages.TransferDst to the texture initialization, allowing the texture to be used as a sampled texture and as a transfer destination, in addition to its previous usages as a color attachment and transfer source.
Added UTF-8 BOM to Canvas.cs, CanvasController.cs, and Toolbar.cs. Replaced private field 'context' with public read-only property 'Context' in CanvasController.cs and updated all references accordingly.
- Introduce Particles value to FluidViewMode enum - Refactor BeginRenderPass with single-line color attachments - Simplify reflection texture assignment with ternary operator
Changed GRContext.Flush to use surface argument and added GRContext.Submit(true) call, replacing previous boolean arguments. This aligns with updated API usage and may improve resource management.
Replaces SampleCount enum with IsMultisamplingEnabled boolean in SKTextureDesc. CanvasController now sets IsMultisamplingEnabled when creating textures. SKSurface uses sample count 4 if multisampling is enabled, otherwise 1. Removes SampleCount from SKTextureDesc.
- Import System.Numerics for Vector4 usage. - Move Layout initialization into constructor and set conditionally. - Use Vector4.Zero instead of default in BeginRenderPass. - Assign Layout inline within the if condition for clarity.
- Moved SKFormats.DirectX12 method within SKFormats class; implementation unchanged - Removed Skia SampleCount to uint mapping method from SKFormats - No changes to PixelFormat mapping methods for Skia or Vulkan - Updated SKRenderer.cs to reference relocated SKFormats.DirectX12
Replaced all usages of Layout with RequiredLayout in CanvasController and SKTexture. Removed the Layout property and updated all logic and references to ensure correct layout handling during texture transitions and rendering.
Updated validation message handling to ignore messages containing "ID3D12CommandList::ClearRenderTargetView", as these are known non-errors from Skia with the old D3D12 API. All other messages continue to be printed to the console.
Adjusted code formatting by separating CanClear and IsMultisamplingEnabled properties. Removed IsMultisamplingEnabled from the code. No functional changes; only property order and spacing were modified.
Renamed the IsMultisamplingEnabled property and variable to MSAA in all relevant files. Updated all references, declarations, and usages in Canvas, CanvasController, and Toolbar classes for improved clarity and consistency. No changes to logic or behavior.
Renamed all references from "multisampling" to "msaa" and "MultisamplingWidth" to "MSAAWidth" for improved naming consistency. Updated variables, constants, and SKRect fields in the MSAA toolbar control, including related logic and UI drawing code.
Removed IsAntialias property from SKPaint in Canvas and Toolbar to use default antialiasing. Introduced GRContextOptions in SKRenderer with custom settings (e.g., AvoidStencilBuffers, AllowPathMaskCaching, cache sizes). Updated Direct3D, Metal, and Vulkan GRContext creation to accept options. Set GRContext resource cache limit to 256 MB.
The AllowPathMaskCaching option was removed from GRContextOptions initialization in the SKRenderer class. This option was previously set to true but is no longer present in the updated code.
Refactored object initializations and method calls in FluidSimulation.cs and FluidTankRenderer.cs to use single-line statements. This improves code compactness and readability by consolidating multi-line GridDimensions initialization and BeginRenderPass calls.
There was a problem hiding this comment.
Pull request overview
This PR introduces a SkiaSharp GPU integration layer plus a new cross-platform InkCanvas experiment, while also refining native-object access and synchronization behavior across multiple rendering backends and view implementations. It additionally adjusts FluidTank rendering/shader logic to preserve scene/frame visibility during low-resolution fluid reconstruction and updates a few dependency versions.
Changes:
- Add
Zenith.NET.Extensions.Skia(SkiaSharp GRContext + backend texture wrapping) and a newExperiments/InkCanvassample using it. - Implement/extend
GetNativeObject(NativeObjectType)across DirectX 12 / Metal / Vulkan resources and contexts. - Refine FluidTank formats/shaders and update several view backends (WPF/WinUI/MAUI/WinForms/Avalonia) synchronization/UI dispatch behavior.
Reviewed changes
Copilot reviewed 53 out of 53 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| Zenith.NET.slnx | Adds InkCanvas experiment project to the solution. |
| sources/Zenith.NET/Enums/NativeObjectType.cs | Expands native handle type taxonomy for DX12/Metal/Vulkan interop. |
| sources/Zenith.NET.Vulkan/VKTopLevelAccelerationStructure.cs | Exposes Vulkan acceleration structure native handle. |
| sources/Zenith.NET.Vulkan/VKBottomLevelAccelerationStructure.cs | Exposes Vulkan AS + device address native handles. |
| sources/Zenith.NET.Vulkan/VKTimeline.cs | Exposes Vulkan semaphore native handle. |
| sources/Zenith.NET.Vulkan/VKTexture.cs | Exposes Vulkan image + allocation memory/offset native handles. |
| sources/Zenith.NET.Vulkan/VKHeap.cs | Exposes Vulkan device memory native handle. |
| sources/Zenith.NET.Vulkan/VKGraphicsContext.cs | Exposes Vulkan instance/device/physical device + proc addrs. |
| sources/Zenith.NET.Vulkan/VKFormats.cs | Reorders barrier stage/access flag aggregation (no semantic change intended). |
| sources/Zenith.NET.Vulkan/VKCommandQueue.cs | Exposes Vulkan queue + family index native handles. |
| sources/Zenith.NET.Vulkan/VKCommandBuffer.cs | Exposes Vulkan command buffer native handle. |
| sources/Zenith.NET.Vulkan/VKBuffer.cs | Exposes Vulkan buffer/address/memory/offset native handles. |
| sources/Zenith.NET.Metal/MTLTimeline.cs | Exposes Metal shared event native pointer. |
| sources/Zenith.NET.Metal/MTLTexture.cs | Exposes Metal texture native pointer. |
| sources/Zenith.NET.Metal/MTLGraphicsContext.cs | Exposes Metal device native pointer. |
| sources/Zenith.NET.DirectX12/DXTopLevelAccelerationStructure.cs | Exposes DX12 AS GPU VA + resource handle. |
| sources/Zenith.NET.DirectX12/DXBottomLevelAccelerationStructure.cs | Exposes DX12 BLAS GPU VA + resource handle. |
| sources/Zenith.NET.DirectX12/DXTimeline.cs | Exposes DX12 fence handle. |
| sources/Zenith.NET.DirectX12/DXTexture.cs | Adds CanTransition and exposes DX12 resource native handle; updates constructor signature for wrapped resources. |
| sources/Zenith.NET.DirectX12/DXSwapChain.cs | Updates swapchain texture construction for new DXTexture ctor. |
| sources/Zenith.NET.DirectX12/DXHeap.cs | Updates heap texture construction for new DXTexture ctor. |
| sources/Zenith.NET.DirectX12/DXGraphicsContext.cs | Exposes DX12 adapter/device native handles and updates wrapped texture creation. |
| sources/Zenith.NET.DirectX12/DXFormats.cs | Adjusts DenyShaderResource flag application for depth textures only. |
| sources/Zenith.NET.DirectX12/DXCommandQueue.cs | Exposes DX12 command queue native handle. |
| sources/Zenith.NET.DirectX12/DXCommandBuffer.cs | Exposes DX12 graphics command list native handle; skips transitions when CanTransition is false. |
| sources/Zenith.NET.DirectX12/DXBuffer.cs | Exposes DX12 resource handle + GPU virtual address. |
| sources/Views/Zenith.NET.Views.WPF/ZenithView.cs | Switches UI dispatch to async dispatcher invocation. |
| sources/Views/Zenith.NET.Views.WPF/Surface.cs | Adds D3D11 query-based GPU completion wait before releasing keyed mutex. |
| sources/Views/Zenith.NET.Views.WinUI/ZenithView.WinUI.cs | Adds D3D11 query-based GPU completion wait before releasing keyed mutex. |
| sources/Views/Zenith.NET.Views.WinForms/ZenithView.cs | Switches UI dispatch to async invocation. |
| sources/Views/Zenith.NET.Views.Maui/Platforms/Windows/Surface.cs | Adds D3D11 query-based GPU completion wait before releasing keyed mutex. |
| sources/Views/Zenith.NET.Views.Avalonia/ZenithView.cs | Switches UI dispatch to async dispatcher invocation. |
| sources/Extensions/Zenith.NET.Extensions.Skia/SKTextureDesc.cs | Introduces a Skia texture descriptor used by the new Skia renderer integration. |
| sources/Extensions/Zenith.NET.Extensions.Skia/SKTexture.cs | Adds a disposable wrapper that renders via Skia into a Zenith texture. |
| sources/Extensions/Zenith.NET.Extensions.Skia/SKRenderer.cs | Adds GRContext creation for DX12/Metal/Vulkan and backend texture wrapping. |
| sources/Extensions/Zenith.NET.Extensions.Skia/SKFormats.cs | Adds PixelFormat/usage mappings for Skia backend interop. |
| sources/Extensions/Zenith.NET.Extensions.Skia/Extensions.cs | Adds GraphicsContext extension API for creating SKTextures with renderer caching. |
| sources/Experiments/InkCanvas/Program.cs | Adds InkCanvas entry point. |
| sources/Experiments/InkCanvas/InkCanvas.csproj | Adds experiment project referencing Skia extension + backend implementations. |
| sources/Experiments/InkCanvas/Helpers/CocoaHelper.cs | Adds CAMetalLayer attachment helper for macOS window surfaces. |
| sources/Experiments/InkCanvas/Drawing/Toolbar.cs | Implements drawing UI controls (palette, stroke width, MSAA toggle, clear). |
| sources/Experiments/InkCanvas/Drawing/Stroke.cs | Implements stroke building, smoothing, and erasing via path ops. |
| sources/Experiments/InkCanvas/Drawing/CanvasController.cs | Wires input events to the canvas + manages SKTexture resizing/MSAA toggles. |
| sources/Experiments/InkCanvas/Drawing/Canvas.cs | Implements the main drawing/erasing model with caching and UI integration. |
| sources/Experiments/InkCanvas/App.cs | Sets up windowing/input, selects backend per OS, renders InkCanvas to swapchain. |
| sources/Experiments/FluidTank/FluidTankRenderer.cs | Updates formats and composites; tightens render pass setup formatting; preserves reflection creation logic. |
| sources/Experiments/FluidTank/FluidSimulation.cs | Compacts GridDimensions initialization formatting. |
| sources/Experiments/FluidTank/Assets/Shaders/Scene.slang | Writes alpha for “frame” material to support fluid occlusion logic. |
| sources/Experiments/FluidTank/Assets/Shaders/FluidSurface.slang | Stores linear depth in attributes to support later occlusion checks. |
| sources/Experiments/FluidTank/Assets/Shaders/FluidComposite.slang | Adds frame-occlusion logic so scene/frame stays visible when fluid reconstructs at low res. |
| sources/Experiments/FluidTank/App.cs | Reorders init assignments and window options formatting. |
| sources/Experiments/CornellBox/App.cs | Reorders init assignments and window options formatting. |
| sources/Directory.Packages.props | Updates Avalonia, SkiaSharp, Slangc.NET, Uno.WinUI versions. |
Suppressed comments (2)
sources/Views/Zenith.NET.Views.WPF/Surface.cs:113
- ID3D11DeviceContext::Begin is not valid for an EVENT query (and the current QueryDesc defaults to EVENT). This can trigger debug-layer errors or undefined behavior. Use End(Query) after CopyResource and poll GetData for completion without Begin().
D3D.D3D11DeviceContext.Begin(Query);
D3D.D3D11DeviceContext.CopyResource((ID3D11Resource*)D3D9SharedTexture.Handle, (ID3D11Resource*)D3D11RenderTarget.Handle);
D3D.D3D11DeviceContext.End(Query);
sources/Views/Zenith.NET.Views.Maui/Platforms/Windows/Surface.cs:106
- ID3D11DeviceContext::Begin is not valid for an EVENT query (and the current QueryDesc defaults to EVENT). This can trigger debug-layer errors or undefined behavior. Use End(Query) after CopyResource and poll GetData for completion without Begin().
D3D.DeviceContext.Begin(Query);
D3D.DeviceContext.CopyResource((ID3D11Resource*)backBuffer.Handle, (ID3D11Resource*)Texture.Handle);
D3D.DeviceContext.End(Query);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Updated NuGet.Packaging.props to use version 1.0.0, moving from the 1.0.0-rc release candidate to the stable release.
Removed explicit DeviceContext.Begin/End(Query) calls in Surface.cs and ZenithView.WinUI.cs. Resource copy and query data polling logic remain unchanged.
Summary
Validation
dotnet build Zenith.NET.slnx -c Releasedotnet format --verify-no-changesand declaration-order/flags audits