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

D3D11创建绑定Unordered Access View的2D纹理返回E_INVALIDARG问题

问题说明

我尝试使用GPU对2D数组进行数学运算,将无mipmap、格式为R32_FLOAT的2D纹理绑定Shader Resource View传入计算着色器,该流程运行正常,纹理可成功传入着色器并正常寻址。

但我在为同类2D纹理创建Unordered Access View时遇到阻塞:调用CreateUnorderedAccessView(...)返回E_INVALIDARG,但我无法获取更详细的错误信息。只要使用D3D_BIND_UNORDERED_ACCESS标记,调用CreateTexture2D(...)也会出现相同问题。

我的设备支持D3D11_0和cs_5_0,对应实现代码如下:

HRESULT Create_Simple_Texture_2D(ID3D11Device* device, ID3D11Texture2D** texture, UINT width, UINT height, void* initdata, UINT initsize)
{
    *texture = nullptr; 
    
    UINT elementsize = sizeof(float);
    
    DXGI_FORMAT format = DXGI_FORMAT_R32_FLOAT;

    D3D11_TEXTURE2D_DESC desc = {};
    {

// 该配置可正常运行
//        desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;    // 输入到GPU
//        desc.Usage = D3D11_USAGE_DEFAULT;               // GPU可读写
//        desc.CPUAccessFlags = 0;                        // 无CPU访问权限

// 该配置也可正常运行
//        desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;  // 输入到GPU
//        desc.Usage = D3D11_USAGE_DYNAMIC;             // CPU写入 -> GPU读取
//        desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // CPU可写入

// 该配置同样正常
//        desc.BindFlags = 0;                             // 
//        desc.Usage = D3D11_USAGE_STAGING;               //
//        desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;    // CPU可读取

// 但该配置无法运行:
        desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
        desc.Usage = D3D11_USAGE_DEFAULT;               // GPU可读写
        desc.CPUAccessFlags = 0;                        // 除创建阶段外无CPU访问权限


        desc.Width = width;
        desc.Height = height;
        desc.Format = format;                           // 见上方定义
        desc.ArraySize = 1;                             // 单纹理
        desc.MipLevels = 1;                             // 无额外mipmap
        desc.MiscFlags = 0;
        {
            desc.SampleDesc.Count = 1;
            desc.SampleDesc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
        }
    }

    const UINT expected = desc.Width * desc.Height * desc.ArraySize * elementsize;

    if (initdata && (initsize != expected)) wcprintf("\n\tWARNING: declared array size mismatch in Create_Simple_Texture_2D(...)\n\n");

    D3D11_SUBRESOURCE_DATA sub = {};
    {
        sub.pSysMem = (void*)(new char[expected]);
        sub.SysMemPitch = desc.Width * elementsize;
        sub.SysMemSlicePitch = 0;
        const UINT copysize = min(expected, initsize);
        if (sub.pSysMem && initdata && copysize) memcpy((void*)sub.pSysMem, initdata, copysize);
    }

    HRESULT result = device->CreateTexture2D(&desc, &sub, texture);
    
    if (sub.pSysMem) delete[] sub.pSysMem;

    return result;
}
故障原因与修复方案

故障出在纹理描述的多重采样配置不符合UAV的创建要求:

  • D3D11中Unordered Access View不支持多重采样纹理,你当前SampleDesc.Count虽然设为1(非多重采样),但SampleDesc.Quality错误使用了D3D11_STANDARD_MULTISAMPLE_PATTERN,当采样计数为1时,Quality必须设置为0,否则会触发E_INVALIDARG错误。
  • R32_FLOAT格式本身是支持UAV绑定的,其余参数配置无问题。

修复方法

将代码中SampleDesc的配置修改为如下内容即可:

desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;

调试建议

如果后续遇到类似参数错误,可在创建设备时添加D3D11_CREATE_DEVICE_DEBUG标志开启调试层,即可在IDE的输出窗口看到详细的错误原因说明,大幅提升排查效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 09:06:03