Existem várias ofertas de fornecedores de GPU, como o CodeXL da AMD ou o nSight / Linux GFX Debugger da NVIDIA, que permitem passar por shaders, mas estão ligados ao hardware do respectivo fornecedor.
Deixe-me notar que, embora eles estejam disponíveis no Linux, sempre tive muito pouco sucesso em usá-los lá. Não posso comentar sobre a situação no Windows.
A opção que tenho vindo a utilizar recentemente, é modularizar o meu código de shader via #includes
e restringir o código incluído para um subconjunto comum de GLSL e C ++ & glm .
Quando encontro um problema, tento reproduzi-lo em outro dispositivo para ver se o problema é o mesmo, o que sugere um erro lógico (em vez de um problema no driver / comportamento indefinido). Há também a chance de passar dados errados para a GPU (por exemplo, buffers incorretamente ligados etc.), os quais eu geralmente descarto depurando a saída como na resposta CIFZ ou inspecionando os dados via apitrace .
Quando se trata de um erro lógico, tento reconstruir a situação da GPU na CPU chamando o código incluído na CPU com os mesmos dados. Então eu posso passar por isso na CPU.
Com base na modularidade do código, você também pode tentar escrever de forma mais unida para ele e comparar os resultados entre uma execução de GPU e uma CPU. No entanto, você deve estar ciente de que existem casos em que o C ++ pode se comportar de maneira diferente do GLSL, fornecendo falsos positivos nessas comparações.
Por fim, quando não é possível reproduzir o problema em outro dispositivo, você pode apenas começar a descobrir de onde vem a diferença. As unittests podem ajudá-lo a diminuir onde isso acontece, mas no final você provavelmente precisará escrever informações adicionais de depuração do shader, como na resposta cifz .
E para lhe dar uma visão geral, aqui está um fluxograma do meu processo de depuração:
Para finalizar, aqui está uma lista de prós e contras aleatórios:
pró
- avançar com o depurador usual
- diagnósticos adicionais (geralmente melhores) do compilador
vigarista