You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

DirectX 11带初始数据创建纹理失败,HRESULT参数错误求助

解决DirectX 11创建带初始数据的R8_UINT纹理失败问题

我帮你排查出了问题的核心:初始数据的内存布局和纹理格式要求不匹配,这才导致CreateTexture2D返回"参数不正确"的错误。下面分点拆解原因,再给你修正后的代码:

1. 数据类型和纹理格式不匹配

你设置的纹理格式是DXGI_FORMAT_R8_UINT,这意味着每个像素只占1个无符号字节,但最开始你用UINT*(4字节/元素)来分配内存:

UINT* data = (UINT*)malloc(sri_w * sri_h * sizeof(UINT));

哪怕你把每个UINT都设为0,内存里每个"像素"实际占了4字节,和纹理期望的1字节完全对不上,DirectX根本没法正确解析这个数据,自然创建失败。

2. SysMemPitch参数设置错误

D3D11_SUBRESOURCE_DATA::SysMemPitch要求的是每行数据的字节数,不是像素数:

  • UINT*的时候,每行字节数应该是sri_w * sizeof(UINT),但R8_UINT纹理只认sri_w * sizeof(unsigned char)的行字节数,两者不匹配直接触发参数错误。
  • 就算你后来改成unsigned char*,如果没同步调整SysMemPitch的设置逻辑(或者代码改得不彻底),还是会出问题。

修正后的完整代码

下面是调整后的正确实现,解决了上面两个问题,还加了内存泄漏防护:

UINT dwRtWidth = 2560;
UINT dwRtHeight = 1440;
D3D11_TEXTURE2D_DESC srcDesc;
ZeroMemory(&srcDesc, sizeof(srcDesc));

int sri_w = dwRtWidth / NV_VARIABLE_PIXEL_SHADING_TILE_WIDTH;
int sri_h = dwRtHeight / NV_VARIABLE_PIXEL_SHADING_TILE_HEIGHT;

srcDesc.Width = sri_w;
srcDesc.Height = sri_h;
srcDesc.ArraySize = 1;
srcDesc.Format = DXGI_FORMAT_R8_UINT;
srcDesc.SampleDesc.Count = 1;
srcDesc.SampleDesc.Quality = 0;
srcDesc.Usage = D3D11_USAGE_DEFAULT;
srcDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
srcDesc.CPUAccessFlags = 0;
srcDesc.MiscFlags = 0;

D3D11_SUBRESOURCE_DATA initialData;
// 用unsigned char匹配R8_UINT的1字节/像素格式
unsigned char* data = (unsigned char*)malloc(sri_w * sri_h * sizeof(unsigned char));
if (!data) {
    LOG("Failed to allocate memory for shading rate surface");
    return;
}

// 用memset快速初始化所有像素为0(对应最低着色率)
memset(data, 0, sri_w * sri_h * sizeof(unsigned char));

initialData.pSysMem = data;
// SysMemPitch设为每行的字节数,R8_UINT下就是像素宽度×1字节
initialData.SysMemPitch = sri_w * sizeof(unsigned char);
initialData.SysMemSlicePitch = 0; // 2D纹理不需要设置这个值

HRESULT hr = s_device->CreateTexture2D(&srcDesc, &initialData, &pShadingRateSurface);
if (FAILED(hr)) {
    LOG("Texture not created");
    LOG(std::system_category().message(hr));
    free(data); // 创建失败也要释放内存,避免泄漏
} else {
    LOG("Texture created");
    free(data);
}

额外要注意的点

  • 确认NV_VARIABLE_PIXEL_SHADING_TILE_WIDTHNV_VARIABLE_PIXEL_SHADING_TILE_HEIGHT是正确的常量(一般是16,对应VRS的16x16 tile),确保sri_wsri_h是整数,不然纹理宽高设置无效也会触发参数错误。
  • 内存分配后一定要做空指针检查,别直接访问非法内存。
  • 不管纹理创建成功还是失败,都要释放堆上分配的data缓冲区,避免内存泄漏。

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

火山引擎 最新活动