HLSL缓冲区跨度和线程 - 这里发生了什么?

时间:2012-09-12 20:51:12

标签: c++ directx hlsl directx-11 directcompute

我是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示例进行了整合。如果我做了一件非常糟糕的事情,请随时告诉我。我真的很喜欢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 个答案:

答案 0 :(得分:0)

我已经尝试过了,但我得到了正确的结果。 由于我的声誉不高,我无法添加评论。 这是我的代码。

HLSL:

RWStructuredBuffer输出:寄存器(u0);

[numthreads(1,1,1)]

void main(uint3 DTid:SV_DispatchThreadID)

{     if(DTid.x&gt; 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 ++:

定义PathName

L&#34; C:\用户。\ E \桌面\ D3D_Reseach \ RenderPro \ 64 \调试\ ComputeShader.cso&#34;

struct Buffer

{

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(),_ Node.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;

}

}