审阅日期:2026-07-17
基线文档:/Users/xiaoyi12/Downloads/dxmt_d3d12_metal4_test_plan.md
审阅范围:原测试计划、当前 tests/d3d12、tests/coverage/d3d12_coverage.json,以及 src/d3d12 中公开接口和明确的 unsupported/error 分支。
原计划对 command list、legacy barrier、descriptor、resource/copy、shader、graphics、query、sparse 和 fault injection 的框架已经很完整。当前仓库也已经从原计划所述的约 118 个测试增长到:
- 121 个已注册的 D3D12
_spec.cpp文件; - 700+ 个静态 GoogleTest 声明,另有参数矩阵生成的逻辑 case;
- 21 个 D3D12 测试目录;
- public API coverage manifest 审阅时只列出 85 个方法;第一轮扩展到 96 个,第二轮扩展到 110 个,第三轮扩展到 137 个,但距离完整 COM surface 仍有缺口;第五轮补入已有行为测试支撑的 9 个漏项, 第六轮加入 Agility/configuration 分类,当前为 165 个。
下一批不应继续优先堆叠已有的 descriptor/copy 基础 case,而应补以下三类空洞:
- 原计划没有覆盖的公开接口和实际游戏链路;
- 原计划只按“unsupported”处理、但当前代码已经开始支持的能力;
- 已有基础测试,但缺少状态、失败、跨进程或端到端 oracle 的能力。
tests/coverage/d3d12_coverage.json 审阅时只登记 85 个 API,未覆盖大量已经出现在当前 COM vtable 中的方法。第一轮补入 11 个 versioned device/resource API;第二轮补入 custom/existing heap、device control 和 marker/event API;第三轮补入 protected session、state/meta/raytracing device 面和 versioned optional command 面;第五、六轮继续补入漏项和 Agility/configuration 分类,当前共 165 个。后续继续把 manifest 扩展为当前 headers/实现的完整清单,再允许以“API coverage 100%”作为门槛。
每个公开方法必须归入原计划定义的 A/B/C 之一:
- A:positive + negative + lifecycle/state;
- B:明确 unsupported + capability coherence + output/no-mutation/recovery;
- C:规范允许 no-op + no-op 不改变前后状态。
建议新增:
tests/d3d12/device/versioned_api_spec.cpp
tests/d3d12/device/device_control_spec.cpp
tests/d3d12/resource/versioned_resource_spec.cpp
tests/d3d12/resource/existing_heap_spec.cpp
tests/d3d12/command/marker_event_spec.cpp
首批补齐的方法:
CreateCommandQueue1
CreateCommittedResource1
CreateCommittedResource2
CreateHeap1
CreatePlacedResource1
CreateReservedResource1
GetResourceAllocationInfo2
GetCustomHeapProperties
SetStablePowerState
SetBackgroundProcessingMode
CreateShaderCacheSession
ShaderCacheControl
CheckDriverMatchingIdentifier
CreateLifetimeTracker
RemoveDevice
GetProtectedResourceSession
SetViewInstanceMask
SetProtectedResourceSession
BeginEvent / EndEvent / SetMarker(list 和 queue)
核心 case:
VersionedResourceSpec.CreateCommittedResource1WithoutSessionMatchesBaseApi
VersionedResourceSpec.CreateCommittedResource2PreservesDesc1Fields
VersionedResourceSpec.CreatePlacedResource1MatchesBasePlacementAndGpuVa
VersionedResourceSpec.GetResourceAllocationInfo2MatchesV1Layout
VersionedDeviceSpec.CreateCommandQueue1MatchesBaseQueueContract
DeviceControlSpec.BackgroundProcessingSignalsEventAndClearsDesireFlag
DeviceControlSpec.StablePowerStateMatchesReferencePolicy
ShaderCacheSessionSpec.UnsupportedCreationClearsOutputAndControlIsCoherent
MarkerEventSpec.MarkersDoNotChangeExecutionOrCommandListState
完成标准:manifest 中当前公开方法 100% 被分类;不能再用“测试源码中出现过方法名”代替行为覆盖。
截至第二轮已完成:
第一轮:11 个 versioned device/resource API case,manifest 85 -> 96
第二轮:12 个 custom/existing heap、device control、marker/event case,
manifest 96 -> 110
第三轮:9 个 raytracing/VRS/protected/state-object fail-closed case,
manifest 110 -> 137
第四轮:7 个 swapchain frame/lifecycle/contract case;DXGI 不计入 D3D12
public API manifest,manifest 保持 137
第五轮:4 个 sampler-feedback/atomic-copy/stream-output case,并强化
AtomicCopy UINT64 lifecycle;manifest 137 -> 146
第六轮:6 个 Agility factory/DRED/configuration COM case,
manifest 146 -> 165
第七轮:4 个 shared-device 合法并发 case,manifest 保持 165
第八轮:5 个 graphics shader system-value case,manifest 保持 165
第九轮:4 个 pipeline cache invalidation/stability case,manifest 保持 165
第十轮:3 个 pixel depth-output system-value case,manifest 保持 165
第十一轮:3 个 structured UAV counter/append/decrement case,manifest 保持 165
第十二轮:2 个 SampleGrad case,并纠正 SampleLevel bias contract,manifest 保持 165
GetCustomHeapProperties:修正并覆盖 CUSTOM type、UMA page/pool 和 NodeMask
OpenExistingHeapFromAddress:覆盖有效 VirtualAlloc -> placed buffer -> GPU copy
OpenExistingHeapFromFileMapping / CreateLifetimeTracker:覆盖 fail-closed 和输出清空
CheckDriverMatchingIdentifier:与未宣称 Raytracing capability 保持一致
SetMarker / BeginEvent / EndEvent:list 和 queue 均覆盖执行与 fence 不变
SetViewInstanceMask / SetProtectedResourceSession(nullptr):覆盖合法执行不变
Present:覆盖 prior queue rendering 顺序与 3 个在途 back buffer 内容隔离
ResizeBuffers:覆盖失败原子性及 GPU 完成、引用释放后的完整重建
Swapchain state:覆盖 source/background/rotation/matrix/fullscreen round-trip
Occlusion/creation:用测试注入覆盖遮挡不推进,以及 device/非法 descriptor
fail-closed;真实 SW_MINIMIZE/窗口脱离仅允许在隔离图形会话或 VM 执行
Sampler Feedback:覆盖旧 UAV 被明确替换为 inert/null binding,GPU 写入无效
AtomicCopy UINT/UINT64:覆盖 E_NOTIMPL 锁存、Reset 拒绝及同 device 新 list 恢复
Stream Output:覆盖非空 target fail-close/recovery 与空 target 合法 no-op
Factory/DRED:覆盖 flags 隔离、独立 identity、脱离 factory 生命周期、全枚举值
Agility concurrency:覆盖 8 线程并发 GetInterface/CreateDeviceFactory
Library subobject deserializer:覆盖失败输出清空并修复早期返回残留指针
Concurrency:覆盖并行对象创建、独立 list 录制、root/query 创建和 fence events
Shader system value:覆盖非零 draw offset 下 draw-local VertexID/InstanceID、
像素中心 Position、相反绕序 FrontFace、triangle-list PrimitiveID 和 ClipDistance
Pixel depth output:覆盖 Depth 覆盖插值值,以及 DepthLessEqual/GreaterEqual
conservative qualifier 参与实际 depth test
Pipeline cache key:覆盖 root 内容/identity、attachment/sample、padding 和
inactive RT state,并将 graphics key 升级到 canonical v3
第四轮运行安全说明:首次 16 条 swapchain 定向运行中,除
ResizeAfterGpuCompletionRecreatesAllBuffers 暴露 trailing barrier 内部引用
误判外,其余 15 条通过;修复后该失败 case 单独通过。随后聚合重跑在宿主
WindowServer 的 detached Metal layer/shared-event 路径触发系统组件断言,因此
不再在当前桌面会话复现。真实窗口最小化已经改为测试注入;最终聚合运行门槛
保留给隔离登录会话或 VM,宿主机只执行编译、静态检查和非 presentation 测试。
RemoveDevice 不能按当前 no-op 行为固化;规范要求进入真正的 device-removed 状态并唤醒 monitored fence,因此保留到 P0-4 的完整状态机一并实现和测试。
第三轮复核修正:当前 D3D12_FEATURE_D3D12_OPTIONS12 明确报告 EnhancedBarriersSupported == FALSE,command list 最高只暴露到 ID3D12GraphicsCommandList6;现有三个 enhanced barrier 正向 case 会按能力 gate 跳过,D3D12OptionalFeatureGateSpec 则验证 ID3D12GraphicsCommandList7 返回 E_NOINTERFACE。因此本节当前是 promotion gate,不能把跳过的正向文件计入执行覆盖。
只有当同一实现变更同时启用 capability 和 ID3D12GraphicsCommandList7::Barrier 后,才必须立即启用以下完整矩阵:
建议新增:
tests/d3d12/sync/enhanced_barrier_matrix_spec.cpp
tests/d3d12/sync/enhanced_barrier_validation_spec.cpp
tests/d3d12/sync/enhanced_legacy_parity_spec.cpp
矩阵至少覆盖:
Barrier type: Global / Buffer / Texture
Queue: Direct / Compute / Copy
Scope: same list / cross list / cross Execute / cross queue + fence
Resource: buffer / 1D / 2D / 3D / array / mip / depth-stencil plane
Subresource: all / single mip / mip range / array range / plane range
Sync/access/layout: 每个被接受或宣称的值
Flags: NONE / DISCARD,以及非法未知位
Batch: 0 / 1 / 31 / 32 / 33 / 255 / 256 / 257
Path: native / fallback / mixed segment
必须加入 metamorphic oracle:
Enhanced transition == equivalent legacy transition
One mixed barrier group == equivalent separated groups
Whole-resource barrier == complete per-subresource barrier set
Same-list ordering == split-list ordering with equivalent fence
负向 case 要验证 Close() 锁存、资源不被半更新、下一条合法 list 可恢复。
原计划把 Pipeline Library 放在“不支持能力一致性”中。当前源码虽然包含 StorePipeline、LoadGraphicsPipeline、LoadComputePipeline、LoadPipeline、Serialize 的内部实现,但 D3D12_FEATURE_SHADER_CACHE 明确报告 NONE,CreatePipelineLibrary 也返回 DXGI_ERROR_UNSUPPORTED。现阶段保留现有 capability coherence 测试;只有在入口真正启用时,才把以下正向测试作为同一变更的 promotion gate。
建议新增:
tests/d3d12/pipeline/library_contract_spec.cpp
tests/d3d12/pipeline/library_execution_spec.cpp
tests/d3d12/pipeline/library_concurrency_spec.cpp
核心 case:
PipelineLibrarySpec.CreatesEmptyLibraryAndExposesStableComIdentity
PipelineLibrarySpec.StoreAndLoadGraphicsPipelineExecutesSamePixels
PipelineLibrarySpec.StoreAndLoadComputePipelineExecutesSameBufferResult
PipelineLibrarySpec.LoadPipelineStreamMatchesCreatePipelineState
PipelineLibrarySpec.DuplicateNameBehaviorMatchesReference
PipelineLibrarySpec.GraphicsComputeTypeMismatchFailsAndClearsOutput
PipelineLibrarySpec.NullNameNullPipelineAndUnsupportedIidAreRejected
PipelineLibrarySpec.CrossDevicePipelineIsRejected
PipelineLibrarySpec.SerializeSizeAndBufferValidationAreCoherent
PipelineLibrarySpec.SerializedBlobReopensInFreshDeviceOrFailsClosed
PipelineLibrarySpec.ConcurrentStoreAndLoadAreRaceFree
其中 duplicate-name、空序列化 blob 和错误 HRESULT 使用 WARP differential packet,不能直接把当前实现行为当作规范。
当前已有若干 fault injection 和 queue error case,但原计划没有形成完整的 device-lost 状态机。Metal command buffer/encoder 的异步失败是翻译层高风险路径,应有可注入、确定性的测试。
建议新增:
tests/d3d12/device/device_removed_spec.cpp
tests/d3d12/device/dred_contract_spec.cpp
tests/d3d12/queue/async_failure_spec.cpp
状态机:
Healthy
-> submit
-> asynchronous Metal failure
-> error latched exactly once
-> pending fence/event completed or cancelled according to policy
-> later submissions rejected without replay
-> objects can be released without hang
-> fresh device/process can recover
核心 case:
DeviceRemovedSpec.InitialReasonIsSuccess
DeviceRemovedSpec.FirstAsynchronousFailureIsSticky
DeviceRemovedSpec.ConcurrentFailuresDoNotReplaceFirstReason
DeviceRemovedSpec.PendingFenceWaitDoesNotHangAfterRemoval
DeviceRemovedSpec.FailedSubmissionDoesNotExecuteCommandsTwice
DeviceRemovedSpec.LaterSubmissionIsRejectedWithoutStateMutation
DeviceRemovedSpec.DeviceAndQueueDestructionDoNotDeadlock
DredSpec.SettingsInterfacesShareIdentityAndAcceptEveryEnablementValue
DredSpec.SettingsObjectLifetimeIsIndependentFromFactory
DredSpec.UnsupportedBreadcrumbOrPageFaultDataFailsClosed
DredSpec.FreshDeviceAfterInjectedFailureExecutesNormally
禁止用真实 GPU hang 做 PR 测试;使用内部 fault point 注入 command-buffer status、encoder creation failure 和 completion callback failure。
原计划完全没有 Swapchain/Present。当前已有创建、基础 Present、ResizeBuffers、tearing、frame latency、color space/HDR 的 contract 测试,但仍缺少“渲染结果真正进入 present 链路”的 oracle 和复杂生命周期。
建议拆分现有文件并新增:
tests/d3d12/presentation/swapchain_contract_spec.cpp
tests/d3d12/presentation/swapchain_frame_semantics_spec.cpp
tests/d3d12/presentation/swapchain_lifecycle_spec.cpp
tests/d3d12/presentation/swapchain_failure_spec.cpp
核心 case:
SwapchainFrameSpec.RenderTransitionPresentAdvancesCorrectBackBuffer
SwapchainFrameSpec.PresentWaitsForPriorQueueRendering
SwapchainFrameSpec.MultipleFramesInFlightPreservePerBufferContents
SwapchainFrameSpec.PresentTestDoesNotConsumeOrAdvanceFrame
SwapchainLifecycleSpec.ResizeAfterGpuCompletionRecreatesAllBuffers
SwapchainLifecycleSpec.ResizeWithOutstandingReferencesFailsAtomically
SwapchainLifecycleSpec.PresentResizeDestroyRaceDoesNotDeadlock
SwapchainContractSpec.CreationRejectsNonQueueObjectAndInvalidDescriptor
SwapchainFrameSpec.BackBufferCannotBeUsedByForeignDeviceCommands
SwapchainContractSpec.MinimizedOrOccludedWindowHasStablePolicy
SwapchainContractSpec.FullscreenSourceSizeRotationAndBackgroundRoundTrip
SwapchainFailureSpec.DeviceRemovalUnblocksFrameLatencyWaiters
若无法稳定读取最终 drawable,增加仅测试构建启用的 native presentation hook,记录 drawable index、提交序号和最终 texture hash;不能只用 Present 返回 S_OK 作为 oracle。
当前已经覆盖部分 Raytracing、Mesh、VRS、Sampler Feedback、Protected Session、Meta Command 和 Sample Position,但每个能力通常只测了一个入口。需要把“capability 未宣称”扩展为完整方法矩阵。
建议生成以下方法族:
Raytracing:
CreateStateObject
AddToStateObject
GetRaytracingAccelerationStructurePrebuildInfo
Build / Copy / EmitPostbuildInfo
SetPipelineState1 / DispatchRays
VRS:
RSSetShadingRate
RSSetShadingRateImage
Sampler feedback:
CreateSamplerFeedbackUnorderedAccessView
Protected resource:
CreateProtectedResourceSession / 1
CreateCommittedResource1 / CreateHeap1 / CreateReservedResource1 with session
Resource::GetProtectedResourceSession
CommandList::SetProtectedResourceSession
Other:
Stream output PSO + SOSetTargets
AtomicCopyBufferUINT / UINT64
non-default OMSetDepthBounds
non-reset SetSamplePositions
suspended/resumed RenderPass
MetaCommand initialization/execution
每个 void command 统一断言:
Close returns explicit failure
failure is sticky
no prior or later command is replayed twice
no hidden state mutation
fresh legal list succeeds
device removed reason remains coherent
截至第五轮,optional_command_contract_spec.cpp 已覆盖 raytracing prebuild
输出清零、Build/Emit/Copy/SetPipelineState1、VRS image、Protected Session
v1/type query、state-object growth、Sampler Feedback inert descriptor、
AtomicCopy UINT/UINT64 和 Stream Output fail-close/no-op。带真实 protected
session/state object 的正向参数路径只有在能力启用后才可成为 must-pass。
原计划有 signature/stage I/O,但未明确列出 D3D12 应用常用的 system-value 语义。当前 shader matrix 主要覆盖算术、控制流、基础 resource、wave、GS/HS/DS。
建议新增:
tests/d3d12/shader/system_value_spec.cpp
tests/d3d12/shader/stage_io_matrix_spec.cpp
tests/d3d12/shader/dxbc_dxil_parity_spec.cpp
覆盖:
VS: SV_VertexID / SV_InstanceID
GS/DS/PS: SV_PrimitiveID
PS: SV_Position / SV_IsFrontFace / SV_SampleIndex / SV_Coverage
PS output: SV_Depth / SV_DepthGreaterEqual / SV_DepthLessEqual / SV_Coverage
Clip/cull distance arrays
NoInterpolation / linear / centroid / sample interpolation
Missing component、producer wider than consumer、register packing boundary
DXBC 与 DXIL 同语义结果
native 与 fallback 同语义结果
第八轮新增 shader/system_value_spec.cpp 的 5 个离屏执行 case:
SV_VertexID / SV_InstanceID 在非零 StartVertexLocation /
StartInstanceLocation 下仍从 draw-local 0 开始;pixel SV_Position 报告
x + 0.5, y + 0.5 的像素中心;SV_IsFrontFace 区分相反绕序;
SV_PrimitiveID 在 triangle list 中递增;负 SV_ClipDistance 完整裁掉对应
图元。前四项使用运行时 HLSL 编译,ClipDistance 使用仓库 Wine conformance
测试的预编译 DXBC,以绕过当前 vkd3d HLSL 前端不接受该合法系统值的已知
缺口,并直接覆盖 DXMT 的 DXBC -> Metal system-value 转换。
截至第十轮,同文件再新增 3 个 pixel depth-output case:普通 SV_Depth
覆盖 interpolated depth 并决定最终 depth test,SV_DepthLessEqual /
SV_DepthGreaterEqual 分别保留 air.less / air.greater conservative
qualifier。现有 graphics_edge_semantics_spec.cpp 已覆盖 SV_SampleIndex 输入与
SV_Coverage 输出的 4x MSAA 执行结果,不再重复。尚待补齐插值/packing 矩阵、
DXIL parity,以及单独的 coverage-input oracle。
建议新增:
tests/d3d12/shader/uav_counter_spec.cpp
tests/d3d12/shader/atomic_matrix_spec.cpp
覆盖:
AppendStructuredBuffer / ConsumeStructuredBuffer
CounterOffsetInBytes: 0 / aligned non-zero / last valid / invalid
counter resource 与 data resource 相同或独立时的合法组合
groupshared / raw buffer / structured buffer / typed UAV atomic
Add / And / Or / Xor / Min / Max / Exchange / CompareExchange
返回 original value
单线程、单 group contention、多 group contention
UAV barrier、cross-list、cross-queue 可见性
32-bit;64-bit 仅在 capability 宣称时执行
第十一轮新增 shader/uav_counter_spec.cpp 的 3 个确定性离屏 compute case:
非零初始 counter 从 1 开始执行三次 append,验证写入元素和最终 counter=4;
在 D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT(4096 字节)处绑定独立 counter,
验证非零 CounterOffsetInBytes 生效且 offset 0 标记不被污染;四线程执行
DecrementCounter,验证每个元素恰好被复制一次且 counter 原子递减到 0。
Append 和 decrement 使用 Wine conformance 测试的预编译 SM5 DXBC,以绕过
当前 vkd3d HLSL 前端不识别 AppendStructuredBuffer 的编译限制。现有
resource_semantic_spec.cpp 已覆盖 structured UAV 的 8 种 32-bit atomic op;
后续仍需补 source-level ConsumeStructuredBuffer 编译路径、counter 最后合法位置/
非法 offset、同资源组合、contention、cross-list/cross-queue 和 capability-gated
64-bit atomic 矩阵。
当前只有少量 texture load/gather/sample 和基础浮点边界。补充 Metal 翻译最容易出现差异的组合:
Texture1D / 2D / 3D / Cube / array / MSAA
Load / Sample / SampleLevel / SampleBias / SampleGrad
Gather RGBA / GatherCmp / offset variants
comparison sampling
mip、array slice、cube face、边界坐标、negative zero
UNORM / SNORM / UINT / SINT / FLOAT / sRGB
NaN、Inf、signed zero、subnormal、round-to-even、saturate
precise/no-contraction;16-bit、64-bit 和 min precision 按 capability gate
oracle 采用 exact integer、ULP、分类结果和 DXBC/DXIL metamorphic,不能对所有浮点格式统一使用固定 epsilon。
第十二轮在 descriptor/sampler_matrix_spec.cpp 新增 2 个确定性离屏
compute case:SampleGrad 用显式 DDX/DDY 在 3 级 mip 链中选择 mip0/mip2;
同一梯度在动态 sampler MipLODBias=1 时分别偏移到 mip1/mip2。同时根据
Direct3D 11.3 Functional Specification 对 sample_l 的明确要求,纠正原先
“显式 LOD 忽略 bias”的错误 contract,验证 SampleLevel 的 LOD 0 加 bias 2
后选择 mip2。实现侧为 DXBC sample_l 加入 sampler bias,并在 sample_d
提交 Metal 前用 exp2(bias) 等比缩放 DDX/DDY,保持梯度方向和各向异性比例。
三个目标 contract 及 MinLOD/MaxLOD、address-mode 相关回归均逐个通过。
持久 AIR cache key 已包含 DXMT build version;本地 dirty build 验证 converter
变化时需使用 DXMT_SHADER_CACHE=0 避免复用旧 AIR。尚待补齐 SampleBias、
RGBA gather、GatherCmp、immediate/programmable offset,以及更多 texture shape。
建议新增:
tests/d3d12/graphics/topology_spec.cpp
tests/d3d12/graphics/sample_frequency_spec.cpp
tests/d3d12/graphics/blend_logic_spec.cpp
tests/d3d12/graphics/optional_raster_state_spec.cpp
覆盖:
point/line/triangle list 与 strip、adjacency、strip cut/restart
vertex slot gap、per-instance step rate、zero-size/null view、multi-slot boundary
front-face winding、cull mode、viewport array、negative viewport height policy
dual-source blend、logic op、alpha-to-coverage、independent blend interaction
sample mask、sample-frequency shader、SV_Coverage round-trip
conservative raster、depth bounds、programmable sample positions、view instancing:
宣称则做 framebuffer oracle;未宣称则做完整 fail-closed matrix
render pass suspend/resume、MRT resolve、depth/stencil resolve 的能力一致性
建议新增:
tests/d3d12/resource/custom_heap_spec.cpp
tests/d3d12/resource/existing_heap_spec.cpp
tests/d3d12/object/shared_contract_spec.cpp
覆盖:
GetCustomHeapProperties 与 UMA/cache-coherent capability 一致
OpenExistingHeapFromAddress / OpenExistingHeapFromFileMapping 正向或明确失败
Create*Resource1/2 与 base API 的 desc、allocation、GPU VA、内容等价
GetDesc1 与 GetDesc 一致,受支持的 layout/flags 不丢失
GetHeapProperties null output、committed/placed/reserved 矩阵
shared resource/heap/fence flags 与 Create/OpenSharedHandle 能力一致
ALLOW_CROSS_ADAPTER、SHARED、SHARED_CROSS_ADAPTER 不得出现半支持状态
跨进程 packet:仅在 shared handle 真正支持后加入 must-pass
原计划主要覆盖 descriptor concurrency,缺少跨对象的合法并发。
建议新增:
tests/d3d12/concurrency/queue_submission_spec.cpp
tests/d3d12/concurrency/pipeline_creation_spec.cpp
tests/d3d12/concurrency/fence_event_spec.cpp
tests/d3d12/concurrency/device_shutdown_spec.cpp
覆盖:
不同 command list/allocator 的并行录制
同一 device 上并行创建 resource、PSO、root signature、descriptor heap
多个 queue 的并行提交和 signal/wait
并行 pipeline library store/load、AIR cache miss/hit
SetEventOnCompletion 注册与 Signal/Release 竞争
queue destruction 与 callback arming 竞争
device teardown 时仍有完成回调、cache writer、residency entry
descriptor/resource client ref 已释放但 GPU submission 仍在飞行
只把规范允许的并发列为 conformance;同对象非法并发归 robustness,断言不崩溃而不是固定结果。
截至第七轮,新增 device/concurrency_spec.cpp,覆盖同一 device 上 8 线程
并行创建 resource/descriptor heap/fence、不同 allocator/list 并行录制与
Close、并行创建 root signature/query heap,以及同一 fence 的多个完成事件
并发注册。以上测试只覆盖规范允许的跨对象并发,不执行 command list。
原计划覆盖 cold/warm/corruption,但未充分覆盖真实文件系统和进程边界。
建议新增:
tests/d3d12/cache/process_replay_spec.cpp
tests/d3d12/cache/filesystem_failure_spec.cpp
tests/d3d12/cache/invalidation_key_spec.cpp
覆盖:
两个进程同时首次写同一 cache/archive
writer 被终止后不留下可被误读的半文件
read-only directory、permission denied、disk-full fault、rename failure
corrupt entry 隔离,不污染其他 key
GPU family、OS/Metal version、compiler options、descriptor ABI 变化会 miss
debug name、pointer、padding、无关 PSO state 不会 miss
cold/warm、cache disabled、corrupt fallback 的最终 GPU 输出一致
截至第九轮,新增 cache/invalidation_key_spec.cpp 的 4 个 contract case:
相同序列化 root signature 的不同 COM 对象命中同一 key、root layout 变化必须
miss、attachment format/sample count 变化必须 miss、结构体 padding 和未生效的
RT7 blend state 不得 miss。测试暴露并修复了原 key 对
D3D12_BLEND_DESC/D3D12_DEPTH_STENCIL_DESC 原始内存(含 padding)的哈希,
现改为逐字段和有效状态规范化哈希,并将 graphics cache key 升级为 v3;原有
SampleMask 失效和 cold/warm archive cached-blob 稳定性回归继续通过。跨进程
并发首写、writer 终止和真实 permission/disk/rename failure 仍待隔离进程 harness。
当前已有基础 Agility tests,但原计划未覆盖这部分。继续补:
SDK version/path 选择的进程级隔离
InitializeFromGlobalState / ApplyToGlobalState 顺序和重复调用
多个 factory 的 flags 与 experimental-feature 状态隔离
并发 GetInterface / CreateDeviceFactory
错误 SDK path/version 清空输出并允许后续正确创建
DRED settings object 的 COM contract 和 factory/global 隔离;将来接入
device-removed 数据后再增加创建前后的生效边界
截至第六轮,已覆盖多 factory flags 隔离、DRED settings 两个接口的共同
identity、不同请求的独立 identity、factory 释放后的对象生命周期、所有
D3D12_DRED_ENABLEMENT 值、未知 IID 输出清空,以及并发 interface/factory
创建。CreateVersionedRootSignatureDeserializerFromSubobjectInLibrary 的无效
输入输出清空也已纳入配置接口 contract;真正的 DRED 数据仍随 P0-4 的
device-removal 状态机后续启用。
SetMarker、BeginEvent、EndEvent 即使是 no-op,也需要验证命令执行结果和状态完全不变;如果接入 Metal capture/signpost,再验证嵌套、空 payload、Unicode/PIX payload 和错误嵌套不会破坏提交。
增加小型 apitrace corpus:
descriptor streaming frame
render-pass MRT frame
multi-queue upload/compute/render frame
sparse texture streaming frame
resize/present frame
原始执行与 replay 比较最终 resource hash、提交次数和 native/fallback segment trace。
当前通常是单 node。即使没有多 GPU,也应系统验证:
GetNodeCount == 1 时 NodeMask 0/1 的规范行为
NodeMask 2、多 bit、visible/creation mask 不一致
cross-adapter heap/resource flags 不得被错误接受
跨 device queue/list/allocator/resource/PSO 的所有组合
adapter LUID、DXGI adapter、Metal device identity 一致
真实 linked-adapter 正向测试仅在硬件和实现支持时启用。
补充:
QueryResourceResidency / OfferResources / ReclaimResources 的支持策略
大量 MakeResident/Evict/SetResidencyPriority 交错
budget reservation 改变与资源创建压力
allocation failure 后 residency set 不泄漏
进程内存压力下 cache、descriptor table、sparse mapping 的回收
压力测试不使用固定“必须 OOM 于第 N 次”的 oracle;使用可注入预算保证确定性。
以下能力一旦从 NOT_SUPPORTED 改为支持,必须在同一变更中加入正向执行 suite,不能只修改 capability bit:
Stream Output
Programmable Sample Positions
Depth Bounds
View Instancing
Variable Rate Shading
Sampler Feedback
Mesh Shader
Raytracing
Protected Resource Session
Meta Command
Shader Cache Session
- 自动生成/校验 Public API manifest;
- 把当前所有方法分类为 positive、unsupported 或 no-op;
- 增加缺口报告,禁止 manifest 漏项仍显示 100%。
交付物:API 清单、coverage checker、第一批 versioned API contract tests。
- 完成剩余 Public API/versioned API contract;
- Enhanced Barrier 完整矩阵;
- Device removal/async failure;
- Swapchain frame semantics;
- Optional feature 全命令面 fail-closed。
这些项目优先级最高,因为它们对应“已经暴露/已经开始支持,但行为矩阵还不完整”的路径。
- Shader system value、UAV counter、texture/numeric matrix;
- fixed-function 边界;
- versioned memory/shared contract;
- legal concurrency 和 cache process tests。
- apitrace/真实帧 replay;
- residency/budget 压力;
- multi-adapter 和未来能力 promotion suite;
- 长时间 stress 与多 GPU/OS 配置。
每个新增测试族必须同时满足:
1. 明确 Class:Conformance / Differential / Robustness
2. 有稳定 CaseId 和单 case replay 参数
3. capability gate 不允许把“宣称但执行失败”变成 skip
4. GPU 可观察行为同时跑 native/fallback,或记录为何只有单路径
5. HRESULT 未被规范固定时保留 WARP reference packet
6. 负向 void command 检查 Close、no mutation、no replay、recovery
7. 异步测试有有界超时和明确的 pending/completed oracle
8. 批量矩阵失败能打印第一个 logical case 和完整参数
9. 新公开 API 同步进入 coverage manifest
10. 新 capability 同步增加 advertised-positive 或 unadvertised-negative suite
以下区域当前已经有较多基础与边界测试,除非 coverage、mutation 或真实 bug 指向具体缺口,否则下一批不应继续无差别扩张:
Command list 基础生命周期
Legacy barrier 的 31/32/33 等 entry boundary
Descriptor 基础 shape/copy/table binding
基础 CopyBuffer/CopyTexture/Clear
基础 timestamp/occlusion/predication
Sparse buffer/texture 基础 mapping
基础 format capability query
这些模块后续应以 mutation survivor、未覆盖分支、游戏 trace 或明确 bug 为入口补 case,而不是继续按 API 名称堆测试。