DirectX/DirectCompute ByteAddressBuffer 初始化失败

DirectX/DirectCompute ByteAddressBuffer initialization failed

我无法从我的 C++ 应用程序初始化 ByteAddressBuffer:每个 API 调用都会成功,但在着色器中,数据始终为 0xFF。

为了创建和初始化 ByteAddressBuffer,我使用了下面的函数。 pInitData 指向包含 RGB 图像的缓冲区(uElementSize 为 3,uCount 为像素数)。

// Create a RAW buffer to store the images bits for shader access
HRESULT BIPApplication::CreateRawImageBuffer(
    UINT  uElementSize,
    UINT  uCount,
    void* pInitData)
{
    D3D11_BUFFER_DESC        desc;
    D3D11_SUBRESOURCE_DATA   InitData;
    HRESULT                  hr;

    SAFE_RELEASE(FRawImageBuffer);

    ZeroMemory(&desc, sizeof(desc));
    desc.BindFlags           = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
    desc.Usage               = D3D11_USAGE_DEFAULT;
    desc.CPUAccessFlags      = 0; 
    desc.ByteWidth           = (((uElementSize * uCount) + 15) / 16) * 16;
    desc.MiscFlags           = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
    desc.StructureByteStride = 0; 

    if (pInitData) {
        InitData.pSysMem = pInitData;
        hr = g_pd3dDevice->CreateBuffer(&desc, &InitData, &FRawImageBuffer);
    }
    else
        hr = g_pd3dDevice->CreateBuffer(&desc, NULL, &FRawImageBuffer);

#if defined(_DEBUG) || defined(PROFILE)
    if (SUCCEEDED(hr) && (FRawImageBuffer != NULL))
        FRawImageBuffer->SetPrivateData(WKPDID_D3DDebugObjectName,
                                        sizeof("RawImageBuffer"),
                                        "RawImageBuffer");
#endif
    return hr;
}

然后我创建一个供计算着色器使用的着色器资源视图:

// Create a shader resource view on the RAW image buffer
HRESULT BIPApplication::CreateRawImageShaderResourceView()
{
    D3D11_BUFFER_DESC               descBuf;
    D3D11_SHADER_RESOURCE_VIEW_DESC desc;

    ZeroMemory(&descBuf, sizeof(descBuf));
    FRawImageBuffer->GetDesc(&descBuf);

    ZeroMemory(&desc, sizeof(desc));
    desc.ViewDimension         = D3D11_SRV_DIMENSION_BUFFEREX;
    desc.BufferEx.FirstElement = 0;
    desc.Format                = DXGI_FORMAT_R32_TYPELESS;
    desc.BufferEx.Flags        = D3D11_BUFFEREX_SRV_FLAG_RAW;
    desc.BufferEx.NumElements  = descBuf.ByteWidth / 4;
    return g_pd3dDevice->CreateShaderResourceView(FRawImageBuffer, &desc, &FRawImageSRV);
}

然后在 Render() 函数中,我将 SRV 传递给着色器:

// For ComputeShader RAW image data
aRViews[0] = FRawImageSRV;
g_pImmediateContext->CSSetShaderResources(0, 1, aRViews);

在电脑着色器中声明:

ByteAddressBuffer              RawImage    : register(t0);
RWTexture2D<float4>            Output      : register(u0);

输出是在屏幕上呈现的 texture2D。 ByteAddressBuffer 是这样使用的:

Value   = RawImage.Load4(0);
Color.b = Value[0];
Color.g = Value[1];
Color.r = Value[2];
Color.a = 1;
Output[DTid.xy] = Color;

在显示器上我只看到白色,而 RGB 值为 (226, 200, 170),即蓝天。

您可能需要查看完整代码,我已经准备了一个包含完整 MSVC2015 解决方案的 zip 文件。在这里下载:BIPApplication.zip

感谢任何帮助。

我找到问题了。我完全不是初始化原始缓冲区的问题,它在着色器中,以我解释字节和颜色的方式。

颜色分量实际上在 0 和 1 之间浮动。 Load4() returns 4 个连续的整数。那不是我需要的。我需要使用一个 Load() 来获取一个整数,然后使用 shift 和 mask 从 32 位整数中提取正确的字节。