You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用ClearUnorderedAccessViewFloat?D3D12 UAV清除报错解决

解决D3D12 ClearUnorderedAccessViewFloat 无效描述符错误

问题根源

你使用的D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE标志描述符堆是CPU仅写、GPU只读的,而ClearUnorderedAccessViewFloat函数要求CPU能读取UAV描述符,直接复用同一个堆会触发错误。需要创建两个独立的描述符堆:

  • 带D3D12_DESCRIPTOR_HEAP_FLAG_NONE:供CPU操作(如Clear),CPU可读可写
  • 带D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE:供GPU着色器访问

修改步骤

1. 创建双描述符堆

分别创建CPU可见和GPU可见的UAV堆:

// CPU可见UAV堆(用于Clear操作)
D3D12_DESCRIPTOR_HEAP_DESC cpu_uav_heap_desc{};
cpu_uav_heap_desc.NumDescriptors = 1; // 根据实际资源数调整
cpu_uav_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
cpu_uav_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
d3d.device->CreateDescriptorHeap(&cpu_uav_heap_desc, IID_PPV_ARGS(&m_cpu_uav_heap));

// GPU可见UAV堆(用于着色器访问)
D3D12_DESCRIPTOR_HEAP_DESC gpu_uav_heap_desc{};
gpu_uav_heap_desc.NumDescriptors = /* 你的资源数量 */;
gpu_uav_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
gpu_uav_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
d3d.device->CreateDescriptorHeap(&gpu_uav_heap_desc, IID_PPV_ARGS(&m_gpu_uav_heap));

// 获取描述符增量大小
m_uav_desc_size = d3d.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

2. 为同一纹理创建双UAV描述符

给两个堆分别创建指向m_texture1d的UAV描述符,确保关联同一资源:

// 定义UAV参数(匹配RWTexture1D<float>)
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc{};
uav_desc.Format = DXGI_FORMAT_R32_FLOAT;
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1D;
uav_desc.Texture1D.MipSlice = 0;

// 给CPU堆创建UAV描述符
D3D12_CPU_DESCRIPTOR_HANDLE cpu_uav_handle = m_cpu_uav_heap->GetCPUDescriptorHandleForHeapStart();
d3d.device->CreateUnorderedAccessView(m_texture1d, nullptr, &uav_desc, cpu_uav_handle);

// 给GPU堆创建UAV描述符
D3D12_CPU_DESCRIPTOR_HANDLE gpu_uav_cpu_handle = m_gpu_uav_heap->GetCPUDescriptorHandleForHeapStart();
d3d.device->CreateUnorderedAccessView(m_texture1d, nullptr, &uav_desc, gpu_uav_cpu_handle);

3. 修正Clear函数调用

传入对应堆的句柄,满足CPU读、GPU访问的要求:

// 获取GPU堆的GPU句柄(供着色器使用)
CD3DX12_GPU_DESCRIPTOR_HANDLE gpu_handle(
    m_gpu_uav_heap->GetGPUDescriptorHandleForHeapStart(),
    0, // UAV在堆中的索引,按需调整
    m_uav_desc_size
);

// 获取CPU堆的CPU句柄(供Clear使用)
CD3DX12_CPU_DESCRIPTOR_HANDLE cpu_handle(
    m_cpu_uav_heap->GetCPUDescriptorHandleForHeapStart(),
    0, // 对应索引
    m_uav_desc_size
);

FLOAT const clear_value = 0;
m_cmd_list->ClearUnorderedAccessViewFloat(
    gpu_handle,
    cpu_handle,
    m_texture1d,
    &clear_value,
    0,
    nullptr
);

4. 绑定GPU堆到命令列表

执行着色器前,将GPU可见堆绑定到命令列表:

ID3D12DescriptorHeap* heaps[] = { m_gpu_uav_heap };
m_cmd_list->SetDescriptorHeaps(_countof(heaps), heaps);

核心说明

两个堆的UAV描述符均指向同一个m_texture1d资源,只是分工不同:CPU堆满足Clear函数的读取要求,GPU堆保障着色器的访问权限。

内容的提问来源于stack exchange,提问作者0xbadf00d

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:52:49