Leitura de saída do Shader Geometry na CPU
-
21-09-2019 - |
Pergunta
Estou tentando ler a saída de um shader de geometria que está usando o fluxo de saída para aumentar para um buffer.
O buffer de saída usado pelo shader de geometria é descrito assim:
D3D10_BUFFER_DESC vbdesc =
{
numPoints * sizeof( MESH_VERTEX ),
D3D10_USAGE_DEFAULT,
D3D10_BIND_VERTEX_BUFFER | D3D10_BIND_STREAM_OUTPUT,
0,
0
};
V_RETURN( pd3dDevice->CreateBuffer( &vbdesc, NULL, &g_pDrawFrom ) );
O shader de geometria cria vários triângulos com base em um único ponto (no máximo 12 triângulos por ponto) e, se eu entender o SDK corretamente, tenho que criar um recurso de estadiamento para ler a saída do shader de geometria na CPU.
Eu declarei outro recurso de buffer (desta vez definindo a bandeira de estadiamento) como este:
D3D10_BUFFER_DESC sbdesc =
{
(numPoints * (12*3)) * sizeof( VERTEX_STREAMOUT ),
D3D10_USAGE_STAGING,
NULL,
D3D10_CPU_ACCESS_READ,
0
};
V_RETURN( pd3dDevice->CreateBuffer( &sbdesc, NULL, &g_pStaging ) );
Após a primeira chamada do aplicativo, o shader de geometria é feito criando todos os triângulos e pode ser desenhado. No entanto, após essa primeira chamada de sorteio, gostaria de poder ler a saída dos vértices pelo Shader Geometria.
Usando o recurso de estadiamento de buffer, estou tentando fazer assim (logo após a primeira chamada):
pd3dDevice->CopyResource(g_pStaging, g_pDrawFrom]);
pd3dDevice->Flush();
void *ptr = 0;
HRESULT hr = g_pStaging->Map( D3D10_MAP_READ, NULL, &ptr );
if( FAILED( hr ) )
return hr;
VERTEX_STREAMOUT *mv = (VERTEX_STREAMOUT*)ptr;
g_pStaging->Unmap();
Isso compila e não dá nenhum erro em tempo de execução. No entanto, pareço não estar obtendo nenhuma saída.
O Shader Geometria produz o seguinte:
struct VSSceneStreamOut
{
float4 Pos : POS;
float3 Norm : NORM;
float2 Tex : TEX;
};
E o vertex_streamout é declarado assim:
struct VERTEX_STREAMOUT
{
D3DXVECTOR4 Pos;
D3DXVECTOR3 Norm;
D3DXVECTOR2 Tex;
};
Estou perdendo alguma coisa aqui?
Solução
Problema resolvido criando o buffer de recursos de estadiamento como este:
D3D10_BUFFER_DESC sbdesc;
ZeroMemory( &sbdesc, sizeof(sbdesc) );
g_pDrawFrom->GetDesc( &sbdesc );
sbdesc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
sbdesc.Usage = D3D10_USAGE_STAGING;
sbdesc.BindFlags = 0;
sbdesc.MiscFlags = 0;
V_RETURN( pd3dDevice->CreateBuffer( &sbdesc, NULL, &g_pStaging ) );
O problema estava no bytewidth.