Em todos os exemplos de código que eu observei, o loop do jogo se parece com isso:
while(true)
{
InputAndUpdate();
Draw();
SwapBuffers();
}
No entanto, isso não destrói o paralelismo entre a CPU e a GPU? Após a chamada dos buffers de troca, a GPU ficará ociosa enquanto a CPU estiver lidando com entradas e atualizações. Então, quando a CPU terminar de emitir comandos de desenho, aguarda até que a GPU termine de renderizar. Por que não é feito assim? :
while(true)
{
Draw(); //First issue the draw commands
InputAndUpdate(); //Update while the GPU is busy rendering
SwapBuffers(); //Now block and wait for the GPU to finish
}
architecture
rendering
game-loop
Hannesh
fonte
fonte
Respostas:
Isso seria verdade, a menos que você tenha um buffer traseiro extra para renderizar (buffer duplo). Isso permite que a CPU continue e faça coisas sem ter que esperar a troca real do buffer (o que normalmente seria o caso, pois você não poderia começar a modificar o buffer traseiro até que ele fosse copiado para o buffer frontal sem risco de corrompendo o que você acabou de renderizar). Quando uma chamada ou troca é efetuada, a solicitação entra em um buffer de comandos que a GPU pode processar, permitindo que a CPU continue fazendo outras coisas enquanto a GPU está atrasada. É assim que o hardware moderno obtém paralelismo. Eu acredito que o D3D tem um limite de quantos quadros você pode render antes de um "Swap" bloquear (você '
O conceito de um loop de jogo como os dois exemplos acima é bastante antigo. Com a introdução de várias unidades de processamento na CPU, você pode estar fazendo renderização em um thread enquanto faz algum trabalho de "atualização" em um ou mais outros. Você pode querer examinar o conceito de filas de tarefas para ajudar a maximizar toda a potência de processamento da CPU disponível.
fonte
a solução que você sitou não faz com que a CPU e a GPU funcionem parrarel, apenas muda a ordem em que elas estão esperando uma pela outra, pois como a outra resposta implica desenhar, sempre coloque seus resultados em um backbuffer e, usando swapbuffers, você apenas altera o que é necessário. monitore o shooting com a última coisa desenhada, para aproveitar todo o potencial da CPU e da GPU, você deve chamar draw e update em dois threads diferentes e usar outro segundo buffer para o que a CPU está fazendo (para que, quando a CPu estiver gerando atualização, resulte no buffer 2 GPU lida no Buffer 1 e quando a CPU está trabalhando com o Buffer 1, a GPu usa o Buffer 2 da mesma forma que os buffers de troca que a GPU usa para evitar alterações no quadro já desenhado)
fonte