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

如何用ID3D11Device::CreateTexture2D创建带Mipmap的纹理数组?

解决DirectX 11纹理数组同时设置ArraySize和MipLevels时CreateTexture2D失败的问题

你遇到的0x80070057(无效参数)错误,核心原因是子资源数据的排列顺序不符合DirectX 11的要求。

DirectX 11中,纹理数组的子资源布局规则是:先遍历所有Mip层级,再切换到下一个数组元素。换句话说,子资源的索引顺序是:

  • 数组元素0的Mip 0 → 数组元素0的Mip 1 → ... → 数组元素0的Mip m-1
  • 数组元素1的Mip 0 → 数组元素1的Mip 1 → ... → 数组元素1的Mip m-1
  • ...
  • 数组元素n-1的Mip 0 → ... → 数组元素n-1的Mip m-1

而你的代码里是先按数组索引分组,再填充Mip层级,完全搞反了顺序,导致CreateTexture2D接收的子资源数据和纹理描述不匹配,触发无效参数错误。

修正后的代码

// Setup the description of the texture.
textureDesc.Height = height;
textureDesc.Width = width;
textureDesc.MipLevels = mipLevels;
textureDesc.ArraySize = count;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_IMMUTABLE;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;

D3D11_SUBRESOURCE_DATA* subData = new D3D11_SUBRESOURCE_DATA[count * mipLevels];

// 修正子资源顺序:先遍历Mip层级,再遍历数组元素
for (int m = 0; m < mipLevels; ++m)
{
    int currentWidth = width >> m;
    if (currentWidth == 0) currentWidth = 1; // 确保最小Mip层级宽度至少为1

    for (int i = 0; i < count; ++i)
    {
        int subResourceIndex = m * count + i;
        if (m == 0)
        {
            // Mip 0使用原始图像数据
            subData[subResourceIndex].pSysMem = imageDataArray[i];
            subData[subResourceIndex].SysMemPitch = (UINT)(width * 4);
        }
        else
        {
            // Mip层级>0使用预生成的Mip数据
            subData[subResourceIndex].pSysMem = mipsPtr[i][m-1];
            subData[subResourceIndex].SysMemPitch = (UINT)(currentWidth * 4);
        }
        subData[subResourceIndex].SysMemSlicePitch = 0; // 2D纹理不需要SlicePitch
    }
}

// Create the texture.
HRESULT hResult = device->CreateTexture2D(&textureDesc, subData, &texture);
if (FAILED(hResult))
{
    delete[] subData; // 记得释放内存,避免泄漏
    return false;
}

delete[] subData;

额外注意事项

  • Mip层级尺寸检查:确保每个Mip层级的宽高至少为1,如果原始尺寸不是2的幂,手动计算Mip尺寸时要处理边界情况。
  • 内存泄漏防护:用new分配的subData数组,无论CreateTexture2D成功与否都要释放。
  • 原始数据索引修正:原代码中imageDataArray[i*mipLevels]存在逻辑错误,每个数组元素对应一个Mip0数据,所以修正为imageDataArray[i],可根据实际数据结构调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:13:16