Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,14 @@ class RHIWorkGraphPipeline {
- 静态采样器
- RHIStaticSamplerDescriptor:按索引绑定的采样器集合,便于在管线布局中固定。
- 后端实现要点(DX12)
- 转换为原生采样器描述,分配 CPU/GPU 描述符对,复制到着色器可见区域。
- 转换为原生采样器描述,按完整 descriptor intern 共享 CPU 槽;BindingTable sampler 段才占用 GPU heap。

```mermaid
classDiagram
class RHISampler {
}
class Dx12Sampler {
+NativeCpuDescriptorHandle
+NativeGpuDescriptorHandle
}
RHISampler <|-- Dx12Sampler
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ class RHISampler {
}
class Dx12Sampler {
+NativeCpuDescriptorHandle
+NativeGpuDescriptorHandle
+Release()
}
class MetalSampler {
Expand Down
3 changes: 1 addition & 2 deletions .qoder/repowiki/zh/content/资源管理/视图管理.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ class Dx12TextureView {
+Device
+DescriptorClass
+NativeCpuDescriptorHandle
+NativeGpuDescriptorHandle
+Release()
}
class VulkanTextureView {
Expand Down Expand Up @@ -233,7 +232,7 @@ RHITextureView <|-- MetalTextureView
## 依赖关系分析
- 抽象层依赖:无后端特定类型,仅定义描述符与基类
- DX12 实现依赖:
- 设备与描述符堆管理(AllocateCbvSrvUavDescriptorPair、CopyDescriptorToShaderVisible)
- 设备与描述符堆管理(view 只占 CPU staging;BindingTable 自有 CPU 镜像 + GPU 段,SetBindingTable flush)
- 工具函数进行格式/维度转换与描述符填充
- Vulkan 实现依赖:
- VkImageView 创建与销毁
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,22 +140,20 @@ RHI-->>App : 可用于命令编码阶段的绑定
- 作用:将纹理资源按 mip/数组/维度进行切片,并以特定访问语义(如只读采样、写入)暴露给着色器
- 关键配置:BaseMipLevel、MipCount、BaseArraySlice、ArrayCount、ViewType
- 后端差异:
- D3D12:创建 SRV/UAV 描述符,并复制到可见堆;支持采样反馈特殊路径
- D3D12:创建 SRV/UAV 到 CPU staging;BindingTable 在 SetBindingTable 时再 flush 到自有 GPU 段;支持采样反馈特殊路径
- Vulkan:创建 VkImageView,设置 subresourceRange;通过 GetDescriptorImageInfo 获取绑定信息
- Metal:使用池化纹理视图索引,减少频繁创建开销;支持全视图快速路径
- Metal:创建期锁定 ViewPool 容量,dispose 清 native 槽后再还软件 index;支持全视图快速路径

```mermaid
classDiagram
class RHITextureView {
+ViewType
+Dimension
+NativeCpuDescriptorHandle()
+NativeGpuDescriptorHandle()
}
class Dx12TextureView {
+CreateSRV()
+CreateUAV()
+CopyToShaderVisible()
}
class VulkanTextureView {
+GetDescriptorImageInfo(layout)
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## Product boundary

Keep RHI and backend boundaries explicit. Preserve the maintained Vortice source and patches; do not replace them with an upstream package that lacks the custom behavior.
Keep RHI and backend boundaries explicit. Do not expose backend Heap/Pool/View containers on the public RHI surface. Preserve the maintained Vortice source and patches; do not replace them with an upstream package that lacks the custom behavior.

## Implementation and verification

Expand Down
2 changes: 2 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Output and intermediate paths are isolated by project, platform, RID, configurat

Public native-backed operations enforce platform and ownership boundaries. No capability downgrade or compatibility implementation is permitted to conceal unsupported execution. Current extraction acceptance is tracked by InfinityBrowser TASK-20260907-INFINITYSTACK-EXTRACTION; this document is not a claim that migration gates have passed.

Binding and descriptor strategy stays behind the backend. The public surface is `RHIBindingTable` with `Count` and `SetBindElement(..., arrayIndex)` for finite bindless; RHI does not grow Heap/Pool/View containers. DX12 gives every table group its own CPU mirror plus GPU segment and publishes on `SetBindingTable`; views and interned sampler slots occupy CPU staging only. Vulkan keeps a set per table and pages pools on the device. Metal fills argument tables or reference buffers and locks a private ViewPool at device create. Backends do not resize shader-visible GPU heaps or native pools at runtime.

DX12 requires successful Agility device-factory initialization using the application D3D12 directory and UTF-8 paths. Source references and packages both deploy these assets; missing assets fail explicitly. The maintained binding and evidence are described in docs/SharpGPU/VorticeAgilityPathPatch.md.

Backend implementation tests belong to the independent conformance harness. Infinity.Rendering.Tests has no product friend access. Test migration provenance is recorded in docs/provenance/backend-test-migration.json. Native configuration tests exercise actual Configure/Resolve behavior in isolated load contexts; product code does not contain a separate engine-path enumerator solely for tests.
Expand Down
2 changes: 1 addition & 1 deletion docs/SharpGPU/FeatureAudit-2026.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ ADR-0064 已完成第一个 clean break:公共 raster attachment 只保留 Inp
| GPU file I/O | `StorageQueue` | DirectStorage native + qualified | unavailable/fail closed | MTLIO native/runtime-probed,当前无 Metal-specific qualified evidence | DX12 实装;Metal 部分;Vulkan 无同构是正确结果,命名仍应细分 |
| Sparse 2D/3D | 有 texture API | reserved textures/tile mapping/residency;native Tier4 当前折叠为 RHI Tier3,Tier4-specific 语义/资格未独立公开 | sparse image 2D/3D feature与mapping | sparse/placement texture mapping | 部分:机制存在,2D/3D/MSAA/residency/Tier4 需要拆分 capability 与 GPU evidence |
| Sparse buffer | capability skeleton | 未形成独立可证明 route | unavailable | unavailable | 不得由 sparse texture 推导 |
| Bindless/indexing | BindingTable + typed capabilities | descriptor table/indexing | descriptor indexing 部分 probe;无 descriptor buffer/heap lowering | MTL4 argument table strategy | 部分;strategy 与 limits 需要继续分层 |
| Bindless/indexing | BindingTable + `Count` + `SetBindElement(..., arrayIndex)`;不暴露 Heap/Pool/View 容器 | table 自有 CPU 镜像 + GPU 段;SetBindElement 只写 CPU;SetBindingTable flush `CopyDescriptors` | set + Device pool 页(SetsPerPage 分档 / 超集共页);`vkUpdateDescriptorSets` + BindSet | argument table / reference buffer + 创建期锁定的私有 ViewPool | 公共面已落地为有限 bindless BindingTable;后端 strategy 不进 RHI,也不热换 GPU heap / native pool |
| Barriers/sync | state/barrier/fence/semaphore | Enhanced + classic barrier path | synchronization2 + core barrier path | Metal4 command/memory barrier path | 基础实装;timeline/shared event/external ownership 仍需公共查询 |
| Pipeline cache | 有 factory | native | native | fail closed(当前 blob contract 不同构) | 部分;应引入 typed archive/binary strategy 而非伪 portable blob |
| Video | 无 | 未暴露 D3D12 Video | 未暴露 KHR Video | 未接 VideoToolbox | 缺失但应归 media service,而非 graphics core |
Expand Down
2 changes: 1 addition & 1 deletion docs/SharpGPU/FeatureMatrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ A Successful native capability probe is never a substitute for a Passed Qualifie
| OpacityMicromap | `RayTracing.OpacityMicromap` / `OpacityMicromapSerialization`, `RHIOpacityMicromap`, BLAS triangle attachment, instance `ForceOmm2State` / `DisableOmms` | Typed capability + AccelStruct object model | G4-T13 PASSED: DX12 Tier1_2 + factory/build; Vulkan only when `VK_EXT_opacity_micromap` is enabled, AS + sync2 (1.3 or `VK_KHR_synchronization2`) are enabled, and function pointers load; WindowsQualified tiny 2-state OMM + one-triangle BLAS; independent Vulkan OMM 1/1 | Metal and missing native path Unavailable; Create/Build `Require` throw; unknown format fail-closed; OMM input / triangle-array / index buffers must include `ERHIBufferUsage.AccelStruct` (maps to `MICROMAP_BUILD_INPUT_READ_ONLY`); `DisableOmms` requires BLAS `AllowDisableOmms` and sets native `ALLOW_DISABLE_OMMS`; serialization is honest Unavailable (no fake blob) |
| Motion | `RayTracing.Motion`, motion triangles (`MotionVertexBuffer` / `MotionVertexOffset` / `MotionVertexStride`) and motion instances (`MotionType` / matrix / SRT), `ERHIAccelStructFlag.Motion` | Typed capability + AccelStruct object model | G4-T15 PASSED at SHA `11d5a8c1ba2bb9d131a96458d22e12ff167e3041`: Vulkan Available only when `VK_NV_ray_tracing_motion_blur` is listed, `rayTracingMotionBlur` is enabled, AS deps + function pointers load, and the native motion AS path is used; DX12 Unavailable (no standard D3D12 motion AS); Metal compile-level Available only when `supportsPrimitiveMotionBlur` plus MTL motion triangle / motion instance descriptors bind | Create/Build `Require` throw when Unavailable; `ERHIAccelStructFlag.Motion` must match motion data (XOR fail-closed); failed Update leaves descriptor + native motion mode unchanged; `MotionVertexStride` 0 means `VertexStride`, a different non-zero stride is fail-closed; unknown `MotionType` fail-closed; no silent static path; pipeline ABI **9** is an incompatible revision for the Motion public descriptor (AS is not a pipeline-cache key); SER / HitObject is G4-T14 `BLOCKED_SDK_BINDING` and is not this row |
| MeshShading | `RHIDeviceCapabilities.Mesh.MeshShader` / `Mesh.TaskShader`, mesh raster pipeline and dispatch | Typed capability | native mesh pipeline plus pixel/readback evidence | mesh factories/encoding throw `NotSupportedException` when unavailable; no silent no-op dispatch |
| DescriptorIndexing | `RHIDeviceCapabilities.DescriptorIndexing`, `RHIBindingTableLayoutElement.Count`, `RHIBindingTable.SetBindElement` | Typed capability + API contract | required/optional arrays, namespace mapping, cross-device/disposed validation, pool rollback, dispatch/readback | unsupported native descriptor semantics fail at layout/table creation; no typed dummy descriptors |
| DescriptorIndexing | `RHIDeviceCapabilities.DescriptorIndexing`, `RHIBindingTableLayoutElement.Count`, `RHIBindingTable.SetBindElement(..., arrayIndex)` | Typed capability + API contract | required/optional arrays, `arrayIndex` updates, namespace mapping, cross-device/disposed validation, table-create pool rollback, dispatch/readback | unsupported native descriptor semantics fail at layout/table creation; no typed dummy descriptors |
| StorageQueue | `RHIDeviceCapabilities.Storage.NativeGpuFileIo` / `GpuDecompression` / `RequestCancellation` / `IoPriority`, `RHIStorageQueue` | Independent typed capabilities + API contract | DX12 DirectStorage file → GPU-local buffer/texture → fence → readback under `SharpGpuDirectStorageQualified`; GDeflate / `CancelRequestsWithTag` / queue `Priority` only when the native queue expresses them | non-native backends and missing DirectStorage support throw `NotSupportedException`; Vulkan and unproven dimensions stay Unavailable; no FileStream/map/staging queue fallback |
| PipelineCache | `RHIDeviceCapabilities.PipelineCache.NativeCache`, `RHIPipelineCache` | Typed capability + API contract | cold/warm/restart native hit, typed corrupt/incompatible import, full-key non-collision | unavailable native cache strategy throws `NotSupportedException`; caller owns opaque blobs |
| WorkGraph | `RHIDeviceCapabilities.WorkGraph.Execution`, `RHIWorkGraphPipeline`, `RHIWorkGraphEncoder` | Typed capability | native create/dispatch/readback on each reported strategy | factory/encoding throws `NotSupportedException` when unavailable |
Expand Down
3 changes: 3 additions & 0 deletions docs/VERIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ dotnet test tests/SharpGPU.Conformance.Tests/SharpGPU.Conformance.Tests.csproj `
--results-directory "$out/test-results/source-release"
```

Descriptor-strategy unit tests that do not require a matching GPU host:
`Dx12DescriptorAllocatorTests`, `VulkanBindingTablePlanTests.PoolPolicy_ShouldTierSetsPerPageAndAllowSupersetShareWithinWasteLimit`, and `MetalBindingTablePlanTests.TextureViewPool_ShouldLockFirstSuccessfulCapacityOnTheLadder`. Metal native slot-clear after dispose remains `TODO(UNVERIFIED)` without a Metal host.

On the current Windows x64 host the Release source build completed with zero
errors and the full conformance run passed **289/289**. It exercised the
DirectX 12 and Vulkan compute/draw paths, native memory and synchronization,
Expand Down
22 changes: 10 additions & 12 deletions src/SharpGPU/Dx12/Dx12AccelStruct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,13 @@ internal unsafe class Dx12TopLevelAccelStruct : RHITopLevelAccelStruct, IDx12Des
{
public Dx12Device Device => m_Dx12Device;
public Dx12DescriptorClass DescriptorClass => Dx12DescriptorClass.AccelerationStructure;
public Vortice.Direct3D12.CpuDescriptorHandle NativeCpuDescriptorHandle => m_Descriptors.Staging.CpuHandle;
public Vortice.Direct3D12.GpuDescriptorHandle NativeGpuDescriptorHandle => m_Descriptors.ShaderVisible.GpuHandle;
public Vortice.Direct3D12.CpuDescriptorHandle NativeCpuDescriptorHandle => m_Staging.Descriptor.CpuHandle;
public Vortice.Direct3D12.ID3D12Resource ResultBuffer => m_NativeResultBuffer;
public Vortice.Direct3D12.BuildRaytracingAccelerationStructureDescription NativeAccelStructDescriptor => m_NativeAccelStructDescriptor;

private Dx12Device m_Dx12Device;
private int m_DescriptionHeapIndex;
private Dx12DescriptorPair m_Descriptors;
private bool m_HasDescriptors;
private Dx12CpuDescriptorAllocation m_Staging;
private Vortice.Direct3D12.ID3D12Resource m_NativeResultBuffer;
private Vortice.Direct3D12.ID3D12Resource m_NativeScratchBuffer;
private Vortice.Direct3D12.ID3D12Resource m_NativeInstancesBuffer;
Expand All @@ -71,7 +70,7 @@ public Dx12TopLevelAccelStruct(Dx12Device device, in RHITopLevelAccelStructDescr
{
m_Dx12Device = device;
m_Descriptor = descriptor;
m_DescriptionHeapIndex = -1;
m_HasDescriptors = false;
RHIOpacityMicromapContract.ValidateTlasDescriptor(device, in descriptor);
RHIAccelStructMotionContract.ValidateTlasDescriptor(device, in descriptor);
Span<RHIAccelStructInstance> asInstances = descriptor.Instances.Span;
Expand Down Expand Up @@ -118,16 +117,15 @@ public Dx12TopLevelAccelStruct(Dx12Device device, in RHITopLevelAccelStructDescr
m_NativeScratchBuffer = Dx12RaytracingHelper.CreateBuffer(m_Dx12Device.NativeDevice, (uint)nativeAccelStructPrebuildInfo.ScratchDataSizeInBytes, Vortice.Direct3D12.ResourceFlags.AllowUnorderedAccess, Vortice.Direct3D12.ResourceStates.Common | Vortice.Direct3D12.ResourceStates.UnorderedAccess, Dx12RaytracingHelper.kDefaultHeapProps);
m_NativeResultBuffer = Dx12RaytracingHelper.CreateBuffer(m_Dx12Device.NativeDevice, (uint)nativeAccelStructPrebuildInfo.ResultDataMaxSizeInBytes, Vortice.Direct3D12.ResourceFlags.AllowUnorderedAccess, Vortice.Direct3D12.ResourceStates.Common | Vortice.Direct3D12.ResourceStates.RaytracingAccelerationStructure, Dx12RaytracingHelper.kDefaultHeapProps);

m_Descriptors = m_Dx12Device.AllocateCbvSrvUavDescriptorPair();
m_DescriptionHeapIndex = m_Descriptors.ShaderVisible.Index;
m_Staging = m_Dx12Device.AllocateStagingCbvSrvUavDescriptor(1);
m_HasDescriptors = true;

Vortice.Direct3D12.ShaderResourceViewDescription accelStructSrvDesc = new Vortice.Direct3D12.ShaderResourceViewDescription();
accelStructSrvDesc.Format = Vortice.DXGI.Format.Unknown;
accelStructSrvDesc.ViewDimension = Vortice.Direct3D12.ShaderResourceViewDimension.RaytracingAccelerationStructure;
accelStructSrvDesc.Shader4ComponentMapping = 5768;
accelStructSrvDesc.RaytracingAccelerationStructure.Location = m_NativeResultBuffer.GPUVirtualAddress;
m_Dx12Device.NativeDevice.CreateShaderResourceView(null, accelStructSrvDesc, m_Descriptors.Staging.CpuHandle);
m_Dx12Device.CopyDescriptorToShaderVisible(m_Descriptors);
m_Dx12Device.NativeDevice.CreateShaderResourceView(null, accelStructSrvDesc, m_Staging.Descriptor.CpuHandle);

m_NativeAccelStructDescriptor.Inputs = nativeAccelStructDescriptor;
m_NativeAccelStructDescriptor.DestinationAccelerationStructureData = m_NativeResultBuffer.GPUVirtualAddress;
Expand Down Expand Up @@ -191,10 +189,10 @@ public override void UpdateAccelerationStructure(in RHITopLevelAccelStructDescri

protected override void Release()
{
if (m_DescriptionHeapIndex >= 0)
if (m_HasDescriptors)
{
m_Dx12Device.FreeDescriptorPair(m_Descriptors);
m_DescriptionHeapIndex = -1;
m_Dx12Device.FreeStagingCbvSrvUavDescriptor(m_Staging);
m_HasDescriptors = false;
}
m_NativeResultBuffer.Release();
m_NativeScratchBuffer.Release();
Expand Down
Loading
Loading