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
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
Voy a publicar esto en la mañana (eta 8 horas). No entendí esto hasta más tarde. Pero gracias de antemano! –
@postgoodism: Agregué el código de creación de mi buffer. Déjame saber si necesitas algo más. –