2012-09-12 8 views
7

Sono davvero nuovo alle tecnologie DirectCompute e ho cercato di imparare dalla documentazione sul sito Web msdn, che è .. denso, per non dire altro.HLSL buffer passo falso e threading - cosa sta succedendo qui?

Mi piacerebbe creare un file hlsl di base che includa una matrice 4x4 e una matrice 4xN e restituisca il risultato moltiplicato. Ma dopo aver trascorso un po 'di tempo a giocare con il codice, ho trovato alcune cose strane che non capisco - principalmente con il modo in cui i thread che ho passato elaborano i buffer e i dati di output.

Con tutti questi esempi, passo in due 16 buffer float e ottengo un buffer da 16 float e poi Dispatch con un raggruppamento 4x1x1 - Posso mostrarti il ​​codice, ma onestamente non so ancora cosa potrebbe aiutarmi ad aiutarmi . Fammi sapere se c'è una sezione del mio codice C++ che vuoi vedere.

con il seguente codice:

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; 
} 

ottengo i seguenti valori out:

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 

Questo ha senso per me - il buffer viene analizzato come 4 thread, ciascuno in esecuzione 1 float4 raggruppamento.

con il seguente codice:

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; 
} 

ottengo i seguenti valori fuori:

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 

e con il codice vero e voglio correre:

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]) 
} 

ho la Valori seguenti:

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 

Posso dire che mi manca una cosa fondamentale qui, ma per la vita di me non posso trovare la documentazione appropriata che mi dice come funzionano. Qualcuno potrebbe aiutarmi a capire che cosa sta succedendo in questo codice?

Grazie per il vostro tempo,

Zach

Come un'altra nota, questo codice è stata cribbed insieme utilizzando il Microsoft DirectX SDK (giugno 2010) \ Samples \ C++ \ Direct3D11 \ BasicCompute11 del campione disponibile. Se sto facendo qualcosa di terribilmente sbagliato, sentiti libero di farmelo sapere. Sono VERAMENTE nuovo in HLSL.

Modifica: il mio codice di creazione del buffer.

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); 
} 

Cercando .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; 
} 

ottenuto questo fuori:

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

Potrebbe pubblicare il codice in cui si creano i ID3D11Buffers ed i corrispondenti oggetti ID3D11ShaderResourceView e ID3D11UnorderedAccessView, compresi i contenuti dei vari oggetti * _DESC utilizzati per creare loro? Inoltre, l'impressione casuale: puoi provare a scrivere 0.1, 0.2, 0.3, 0.4 invece di 1,2,3,4 nel secondo esempio? – postgoodism

+0

Lo posterò al mattino (eta 8 ore). Non l'ho capito più tardi. Ma grazie in anticipo! –

+0

@postgoodism: aggiunto il mio codice di creazione del buffer. Fammi sapere se hai bisogno di qualcos'altro. –

risposta

0

ho provato la tua strada, ma ho avuto un risultato corretto Non riesco ad aggiungere il commento a causa della mia poca reputazione. Ecco il mio codice.

HLSL:

RWStructuredBuffer uscita: registro (u0);

[numthreads (1, 1, 1)]

void main (uint3 DTid: SV_DispatchThreadID)

{ se (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: \ Users \ E \ Desktop \ D3D_Reseach \ RenderPro \ x64 \ Debug \ ComputeShader.cso"

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(), Desc, 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

Mi dispiace per pasticcio di codice. –