2012-09-12 35 views
7

我真的很新的DirectCompute技术,并一直试图从MSDN网站,这是..密集的文档来学习,至少可以这样说。HLSL缓冲区跨度和线程 - 这里发生了什么?

我想提出一个基本的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 

我可以告诉我在这里缺少一个关键的事情,但对我的生活我不能找到相应的文档告诉我如何工作的。有人能帮我理解这段代码中发生了什么吗?

感谢您的时间,

扎克

至于另注,此代码是使用微软的DirectX SDK(2010年6月)\样本\ C++ \ Direct3D11 \ BasicCompute11提供样品一起那儿剽窃。如果我正在做一些非常错误的事情,请随时通知我。我真的是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 
+1

你能张贴在那里你创建你ID3D11Buffers和相应的ID3D11ShaderResourceView和ID3D11UnorderedAccessView对象,包括用于创建它们的各种* _DESC对象的内容的代码?另外,随机预感:在第二个例子中,你可以尝试写出0.1,0.2,0.3,0.4而不是1,2,3,4吗? – postgoodism

+0

我会在早上发表(eta 8小时)。直到后来才发现这一点。但预先感谢! –

+0

@postgoodism:添加了我的缓冲区创建代码。需要帮助请叫我。 –

回答

0

我曾尝试用自己的方式,但我得到了一个正确的结果。 由于我的小声望,我无法添加评论。 这是我的代码。

HLSL:

RWStructuredBuffer输出:寄存器(U0);

[numthreads(1,1,1)]

无效的主要(为uint3 DTID:SV_DispatchThreadID)

{ 如果(DTid.x> 4)

return; 

Output[DTid.x].x= 1.f; 

Output[DTid.x].y = 2.f; 

Output[DTid.x].z = 3.f; 

Output[DTid.x].w = 4.f; 

}

C++:

define PathName

L “C:\用户。\ E \桌面\ D3D_Reseach \ RenderPro \ 64 \调试\ ComputeShader.cso”

结构缓冲器

{

XMFLOAT4 Test; 

};

INT APIENTRY wWinMain(HINSTANCE的hInstance,HINSTANCE hPrevInstance,LPTSTR

lpCmdLine,INT的nCmdShow)

{

Hardware HardWare; 

WinSystem Win; 

Win.CreateWindows(HardWare, 400, 300); 

ShowWindow(Win.hwnd, SW_HIDE); 

//UAV 

SharedComPtr<ID3D11UnorderedAccessView> Resource; 

SharedComPtr<ID3D11Buffer>       _Buffer; 

ShaderResourceView::STRUCT_BUUFER_DESC Desc; 

Desc.ACCESS = 0; 

Desc.BIND = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS; 

Desc.FORMAT = DXGI_FORMAT_UNKNOWN; 

Desc.HasScr = false; 

Desc.MISC = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; 

Desc.USAGE = D3D11_USAGE_DEFAULT; 

Desc.ByteWidth= 4 * sizeof(Buffer); 

Desc.StructureByteStride= sizeof(Buffer); 

Desc.UAV_OR_SRV = ShaderResourceView::UAV; 

ShaderResourceView :: CreateStructBuffer(HardWare.GetD3DDevice(),商品说明, nullptr,Resource.GetTwoLevel(),_Buffer.GetTwoLevel(),true);

//CompilerShader 

SharedComPtr<ID3D11ComputeShader>  ComputerSahder; 

SharedComPtr<ID3DBlob>        Blob; 

WCHAR *Name = PathName; 

CompilerShader::CompileShaderFromBinary(ComputerSahder.GetTwoLevel(), Name, HardWare.GetD3DDevice(), 
                   Blob.GetTwoLevel(), CompilerShader::ShaderFlag::ComputeShader); 

//Set ComputerHlsl 

HardWare.GetDeviceContext()->CSSetUnorderedAccessViews(0, 1, 

Resource.GetTwoLevel(),0);

HardWare.GetDeviceContext()->CSSetShader(ComputerSahder.Get(), 0, 0); 

HardWare.GetDeviceContext()->Dispatch(4, 1, 1); 

//SRV 

Buffer Hy[4]; 

VOID *P = Hy; 

ID3D11Buffer* pBuffer; 

BufferSystem::CreateConstanceBuffer(HardWare.GetD3DDevice(), P, pBuffer, 

Desc.ByteWidth,D3D11_USAGE_STAGING);

HardWare.GetDeviceContext()->CopyResource(pBuffer, _Buffer.Get()); 

D3D11_MAPPED_SUBRESOURCE Data; 

HardWare.GetDeviceContext()->Map(pBuffer, 0, D3D11_MAP_READ, 0, &Data); 

Buffer *PP = reinterpret_cast<Buffer*>(Data.pData); 

for (UINT i = 0; i < 4; ++i) { 

    float a = PP[i].Test.x; 

    a = PP[i].Test.y; 

    a = PP[i].Test.z; 

    a = PP[i].Test.w; 

    a = PP[i].Test.w; 

} 

}

+0

对不起一团糟的代码。 –