ComputeWeave 1.4.1
dotnet add package ComputeWeave --version 1.4.1
NuGet\Install-Package ComputeWeave -Version 1.4.1
<PackageReference Include="ComputeWeave" Version="1.4.1" />
<PackageVersion Include="ComputeWeave" Version="1.4.1" />
<PackageReference Include="ComputeWeave" />
paket add ComputeWeave --version 1.4.1
#r "nuget: ComputeWeave, 1.4.1"
#:package ComputeWeave@1.4.1
#addin nuget:?package=ComputeWeave&version=1.4.1
#tool nuget:?package=ComputeWeave&version=1.4.1
ComputeWeave
English | 日本語
ComputeWeave is a fork of ComputeSharp, the library that lets DirectX 12 compute shaders be written entirely in C#. That base is unchanged: a shader is a partial struct implementing IComputeShader, GraphicsDevice.GetDefault() returns the device, and For dispatches.
This package also contains everything the fork adds, which is a declarative layer. A compute pipeline and its resources are declared with attributes, a source generator turns the declaration into a canonical binary descriptor embedded in the assembly, and the runtime reads that descriptor to bind resources, record command lists and track completion. The same layer carries shared textures and shared fences across the Direct3D 11 and Direct3D 12 boundary, and adds a GPU memory budget.
Declarative compute pipelines
A host is a partial type marked with [ComputePipelineHost]. The first argument names the field holding the device, the second is the number of concurrent invocations to reserve. A pipeline is a method marked [ComputePipeline] whose first parameter is in ComputeContext.
using ComputeWeave;
[ComputePipelineHost("device", 1)]
public sealed partial class Host
{
private readonly GraphicsDevice device;
[ComputePipelineResource(ComputeResourceAccess.ReadWrite, ComputeResourceRecovery.Recompute)]
private readonly ComputeResourceSlot<ReadWriteBuffer<int>> index = new();
[ComputePipeline]
private void Run(in ComputeContext context)
{
}
}
The generator emits into the same partial type a static Create factory, Dispose, WaitForDisposal, and for each pipeline an overload of the same name that takes the declared arguments without the context and returns ComputeSubmission.
using Host host = Host.Create(GraphicsDevice.GetDefault(), maximumPendingSubmissions: 4);
ComputeSubmission submission = host.Run();
submission.Wait();
Waiting is explicit; a submission is not awaited implicitly at disposal.
Owned resource slots
A resource owned by a host is declared as a field of ComputeResourceSlot<TResource> or ComputeResourceGroupSlot<TGroup>. The generator emits TryEnsure<Slot>(in <Plan> plan, out bool changed) and, for single-resource slots, Get<Slot>ComputeBinding().
Resources are not held directly; they live in slots that publish generations. A new generation is published only when the requested plan actually changes, and work in flight keeps the generation it captured alive, so resizing a resource does not invalidate submissions already recorded. ComputeResourceRecovery selects what happens to the contents when a generation is replaced: Discardable, RecreateFromHost, Recompute or CapacityOnly.
Direct3D 11 interoperation
An external API is connected by implementing IComputeExternalInteropProvider<TView> and registering it with GraphicsDevice.RegisterExternalDomain. The provider is asked to initialise a shared timeline, to enqueue signals and waits on its own queue, and to open a shared texture as its own view type.
using ComputeInteropDomain domain = device.RegisterExternalDomain(provider);
Shared textures are declared in a partial type marked [ComputeInteropResourceSet], as SharedTextureSlot<T, TPixel, TView> fields annotated with [ComputeSharedTexture].
[ComputeInteropResourceSet]
public sealed partial class ResourceSet
{
[ComputeSharedTexture(
ComputeResourceResizePolicy.Exact,
ComputeResourceAccess.ReadWrite,
ExternalResourceAccess.Write,
ExternalTextureUsage.RenderTarget,
ComputeAlphaMode.Premultiplied,
ComputeSharedTextureInitialOwner.External,
ComputeResourceRecovery.RecreateFromHost)]
private readonly SharedTextureSlot<Bgra32, Float4, ExternalView> source;
}
TryGet<Slot>AllocatedSize reports the allocated width and height of the published texture, which can remain larger than the logical dimensions under GrowOnly. The result is an unpinned snapshot and does not describe a binding, borrow or lease acquired separately when generation replacement can run concurrently. The Width and Height of an ExternalTextureLease<TView> describe the generation held by that lease. Ownership is handed over through the shared fence: BeginExternalOperation borrows the view for the external API, AcquireExternalViewLease takes a lease that outlives a single operation, and GetComputeBinding returns the compute-side binding.
Retiring a shared texture generation drains the external queue before the external view is released, and that drain runs on the device rather than on the calling thread, so the retired generation is still held when TryEnsure or Dispose returns. A foreground operation waits when that internal maintenance operation temporarily holds the domain, while another foreground operation remains a conflicting use and is rejected. A provider that throws poisons its domain, and every later operation on that domain reports the failure.
InteropServices additionally exposes the shared texture and shared fence primitives directly, for callers that manage the handles themselves.
GPU memory budget
GraphicsDevice.SetMemoryPolicy installs hard limits per memory segment and, optionally, an IGraphicsMemoryBudgetBroker that arbitrates between clients. GraphicsDevice.GetMemoryStatistics returns a snapshot and GraphicsDevice.TrimMemory releases what is retired and idle. A generation is idle only once the work and the external queue that held it are done with it, so trimming right after the call that retired it reclaims nothing. Allocation failures caused by the budget surface as GraphicsMemoryAllocationException. The budget covers the resources the device creates itself; a device using an allocator configured through AllocationServices.ConfigureAllocatorFactory creates its resources through that allocator, and those are neither admitted against the policy nor counted in the statistics. A configured allocator and the declarative layer are mutually exclusive: generations, trimming and the budget all rest on the device owning its allocations, so the Create factories throw NotSupportedException on such a device. The base library and InteropServices are unaffected.
Compile-time validation
The declarations above are checked by analyzers that report 95 diagnostics with the CMPW prefix, covering attribute placement, host and pipeline method shape, slot declaration, resource contracts and generated overload conflicts. Some carry a code fix.
More
The complete API reference is in the repository.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- ComputeWeave.Core (>= 1.4.1)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on ComputeWeave:
| Package | Downloads |
|---|---|
|
ComputeWeave.D3D12MemoryAllocator
An extension library for ComputeWeave that uses D3D12MA for graphics resource allocation. |
|
|
ComputeWeave.Dxc
An extension library for ComputeWeave that includes the DXC compiler and enables shader reflection. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.4.1 | 24 | 8/11/2026 |
| 1.4.0 | 61 | 8/10/2026 |
| 1.3.0 | 59 | 8/8/2026 |
| 1.2.4 | 64 | 8/7/2026 |
| 1.2.3 | 66 | 8/7/2026 |
| 1.2.2 | 69 | 8/6/2026 |
| 1.2.1 | 73 | 8/6/2026 |
| 1.2.0 | 122 | 8/3/2026 |
| 1.1.4 | 124 | 8/2/2026 |
| 1.1.3 | 117 | 8/2/2026 |
| 1.1.2 | 131 | 8/2/2026 |
| 1.1.1 | 126 | 8/2/2026 |
| 1.1.0 | 134 | 8/1/2026 |
| 1.0.3 | 117 | 8/1/2026 |
| 1.0.2 | 116 | 8/1/2026 |
| 1.0.1 | 113 | 8/1/2026 |
| 1.0.0 | 123 | 8/1/2026 |