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 位整数中提取正确的字节。
我无法从我的 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 位整数中提取正确的字节。