2012-09-12 13 views
7

Soy realmente nuevo en las tecnologías DirectCompute, y he tratado de aprender de la documentación en el sitio web msdn, que es ... denso, por decir lo menos.zancada y enhebrado del búfer HLSL: ¿qué está pasando aquí?

Me gustaría hacer un archivo hlsl básico que tenga una matriz 4x4 y una matriz 4xN y devuelva el resultado multiplicado. Pero después de pasar algún tiempo jugando con el código, he encontrado algunas cosas raras que no entiendo, principalmente con cómo los hilos que paso procesan los buffers y los datos de salida.

Con todos estos ejemplos, paso en dos 16 buffers flotantes y saco un buffer de 16 flotantes y luego envío con un agrupamiento 4x1x1 - Puedo mostrar su código, pero sinceramente aún no sé qué lo ayudaría a ayudarme . Avíseme si hay una sección de mi código C++ que desea ver.

con el siguiente código:

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

consigo los siguientes valores de salida:

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 

Esto tiene sentido para mí - el buffer se analiza como 4 hilos, cada uno ejecutando 1 float4 agrupación.

con el siguiente código:

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

puedo obtener los siguientes valores de salida:

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 

y con el código real que desea ejecutar:

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

consigo el siguientes valores:

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 

Puedo decir que me estoy perdiendo algo crítico aquí, pero por mi vida no puedo encontrar la documentación apropiada que me diga cómo funcionan. ¿Alguien podría ayudarme a entender qué está pasando en este código?

Gracias por su tiempo,

Zach

Como otra nota, este código fue plagiado junto con el DirectX SDK de Microsoft (junio de 2010) \ Samples \ C++ \ Direct3D11 \ BasicCompute11 muestra disponible. Si estoy haciendo algo terriblemente malo, siéntete libre de avisarme. Soy REALMENTE nuevo en HLSL.

Editar: El código de creación de mi 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); 
} 

Tratando 0.1, 0.2, 0.3, 0.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; 
} 

tiene esto:

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

Podría publicar el código en el que crear sus ID3D11Buffers y los correspondientes objetos ID3D11ShaderResourceView y ID3D11UnorderedAccessView, incluyendo el contenido de los diversos objetos _DESC * utilizados para crearlos? Además, al azar: ¿puedes intentar escribir 0.1, 0.2, 0.3, 0.4 en vez de 1,2,3,4 en el segundo ejemplo? – postgoodism

+0

Voy a publicar esto en la mañana (eta 8 horas). No entendí esto hasta más tarde. Pero gracias de antemano! –

+0

@postgoodism: Agregué el código de creación de mi buffer. Déjame saber si necesitas algo más. –

Respuesta

0

me han tratado a su manera, pero tengo una resultado correcto No puedo agregar el comentario debido a mi poca reputación. Aquí está mi código.

HLSL:

RWStructuredBuffer de salida: registrar (u0);

[numthreads (1, 1, 1)]

void main (uint3 DTID: SV_DispatchThreadID)

{ si (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"

estructura 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(), la descripción, nullptr, Resource.GetTwoLevel(), _Buffer.GetTwoLevel(), verdadero);

//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

Lo siento por desorden de código. –

Cuestiones relacionadas