我对 DirectCompute 技术真的很陌生,并且一直在尝试从 msdn 网站上的文档中学习,至少可以这么说。
我想制作一个基本的 hlsl 文件,它接受一个 4x4 矩阵和一个 4xN 矩阵并返回相乘的结果。但是在花了一些时间玩代码之后,我发现了一些我不理解的奇怪东西——主要是我传入的线程如何处理缓冲区和输出数据。
对于所有这些示例,我传入两个 16 浮点缓冲区并取出一个 16 浮点缓冲区,然后使用 4x1x1 分组进行调度 - 我可以向您展示代码,但老实说,我还不知道什么可以帮助您。如果您想查看我的 C++ 代码的一部分,请告诉我。
使用以下代码:
StructuredBuffer<float4x4> base_matrix : register(t0); // byteWidth = 64
StructuredBuffer<float4> extended_matrix : register(t1); // byteWidth = 64
RWStructuredBuffer<float4> BufferOut : register(u0); // byteWidth = 64, zeroed out before reading from the GPU
[numthreads(1, 1, 1)]
void CSMain( uint3 DTid : SV_DispatchThreadID )
{
BufferOut[DTid.x].x = 1;
}
我得到以下值:
1.000 0.000 0.000 0.000
1.000 0.000 0.000 0.000
1.000 0.000 0.000 0.000
1.000 0.000 0.000 0.000
这对我来说很有意义 - 缓冲区被解析为 4 个线程,每个线程执行 1 个 float4 分组。
使用以下代码:
StructuredBuffer<float4x4> base_matrix : register(t0); // byteWidth = 64
StructuredBuffer<float4> extended_matrix : register(t1); // byteWidth = 64
RWStructuredBuffer<float4> BufferOut : register(u0); // byteWidth = 64, zeroed out before reading from the GPU
[numthreads(1, 1, 1)]
void CSMain( uint3 DTid : SV_DispatchThreadID )
{
BufferOut[DTid.x].x = 1;
BufferOut[DTid.x].y = 2;
BufferOut[DTid.x].z = 3;
BufferOut[DTid.x].w = 4;
}
我得到以下值:
1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000
并使用我要运行的实际代码:
StructuredBuffer<float4x4> base_matrix : register(t0);
StructuredBuffer<float4> extended_matrix : register(t1);
RWStructuredBuffer<float4> BufferOut : register(u0);
[numthreads(1, 1, 1)]
void CSMain( uint3 DTid : SV_DispatchThreadID )
{
BufferOut[DTid.x] = mul(base_matrix[0],extended_matrix[DTid.x])
}
我得到以下值:
0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000
我可以说我在这里遗漏了一件关键的事情,但是对于我的一生,我找不到合适的文档来告诉我这些是如何工作的。有人可以帮我理解这段代码发生了什么吗?
谢谢你的时间,
扎克
另外请注意,此代码是使用 Microsoft DirectX SDK(2010 年 6 月)\Samples\C++\Direct3D11\BasicCompute11 Sample available 编写的。如果我做错了什么,请随时告诉我。我是 HLSL 的新手。
编辑:我的缓冲区创建代码。
CreateStructuredBuffer( g_pDevice, sizeof(float)*16, 1, g_matrix, &g_pBuf0 );
CreateStructuredBuffer( g_pDevice, sizeof(float)*4, NUM_ELEMENTS, g_extended_matrix, &g_pBuf1 );
CreateStructuredBuffer( g_pDevice, sizeof(float)*4, NUM_ELEMENTS, NULL, &g_pBufResult );
//--------------------------------------------------------------------------------------
// Create Structured Buffer
//--------------------------------------------------------------------------------------
HRESULT CreateStructuredBuffer( ID3D11Device* pDevice, UINT uElementSize, UINT uCount, VOID* pInitData, ID3D11Buffer** ppBufOut )
{
*ppBufOut = NULL;
D3D11_BUFFER_DESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
desc.ByteWidth = uElementSize * uCount;
desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
desc.StructureByteStride = uElementSize;
if ( pInitData )
{
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = pInitData;
return pDevice->CreateBuffer( &desc, &InitData, ppBufOut );
} else
return pDevice->CreateBuffer( &desc, NULL, ppBufOut );
}
尝试 .1,.2,.3,.4 ...
StructuredBuffer<float4x4> base_matrix : register(t0);
StructuredBuffer<float4> extended_matrix : register(t1);
StructuredBuffer<uint> loop_multiplier : register(t2);
RWStructuredBuffer<float4> BufferOut : register(u0);
[numthreads(1, 1, 1)]
void CSMain( uint3 DTid : SV_DispatchThreadID )
{
BufferOut[DTid.x].x = .1;
BufferOut[DTid.x].y = .2;
BufferOut[DTid.x].z = .3;
BufferOut[DTid.x].w = .4;
}
把这个弄出来:
0.100 0.100 0.100 0.100
0.100 0.100 0.100 0.100
0.100 0.100 0.100 0.100
0.100 0.100 0.100 0.100