Por que os gráficos vetoriais acelerados por hardware não foram retirados?

88

Estou trabalhando em um aplicativo que envolve a manipulação em tempo real de caminhos vetoriais a 60fps e estou muito surpreso com a pouca informação disponível sobre o assunto. No começo, tentei implementar minha ideia usando o CoreGraphics, mas ela não teve um desempenho adequado para os meus propósitos . Descobri então que havia um padrão Khronos para gráficos vetoriais acelerados por hardware chamado OpenVG e, felizmente, uma alma bondosa havia escrito uma semi-implementação do OpenGL ES chamada MonkVG .

Mas, apesar do OpenVG ser uma API muito útil, parece mais ou menos abandonado pelo Khronos. Segundo a Wikipedia, desde 2011, o grupo de trabalho "decidiu ... não realizar nenhuma reunião regular [sic] para maior padronização". A documentação, melhor que posso encontrar, consiste em apenas um cartão de referência. Além disso, quase não existem exemplos de OpenVG em nenhum lugar da Internet. Eu posso encontrar centenas de tutoriais do OpenGL num piscar de olhos, mas o OpenVG parece conspicuamente ausente.

Você pensaria que os vetores acelerados por hardware seriam mais importantes no mundo atual de resoluções que aumentam rapidamente, e parece que muitas empresas estão implementando suas próprias maneiras de fazer isso. Por exemplo, Qt e Flash possuem esquemas para vetores acelerados por hardware, e muitas das ferramentas da Adobe têm a aceleração por hardware como opção. Mas parece que a roda está sendo reinventada quando um padrão já existe!

Há algo que me falta no OpenVG que o torne inadequado para uso no mundo real? Ou será que o padrão não pegou a tempo e agora está destinado à obscuridade? Você acha que há espaço para uma API padronizada para gráficos vetoriais acelerados por hardware no futuro ou será mais fácil usar as técnicas tradicionais baseadas em varredura? Ou os vetores estão simplesmente saindo, antes de entrar?

Archagon
fonte
14
Antes de rebater esta questão, lembre-se de que questões subjetivas são permitidas para programadores, desde que sejam construtivas, o que eu acho que é essa.
Archagon 21/03
I upvoted porque não parecer uma pergunta ruim ..
O homem de muffin
1
É interessante notar que os gráficos de computador começaram como gráficos vetoriais . Incluindo monitores.
Clockwork-Muse
1
Em primeiro lugar, eu reconheceria o OpenVG falhou porque o setor não confiava depois do desastre que aconteceu com o OpenGL. Estou com preguiça de fazer pesquisas para apoiar essa teoria, então deixarei como um comentário.
Michael Brown
8
@Earlz - diretamente da FAQ: programmers.stackexchange.com/faq - consulte a segunda seção
DXM

Respostas:

34

update: Veja o final da resposta

Essa resposta chega um pouco tarde demais, mas espero esclarecer outras pessoas (principalmente agora que o comitê padrão do C ++ deseja incorporar o Cairo no std):

A razão pela qual ninguém se importa realmente com "gráficos vetoriais acelerados" é o funcionamento das GPUs. As GPUs trabalham com paralelismo maciço e recursos SIMD para colorir cada pixel. A AMD normalmente trabalha em blocos de 64x64 e 8x8 pixels, enquanto as placas NVIDIA geralmente trabalham em 32x32 e 4x4 pixels. [Veja a atualização na parte inferior]

Mesmo que eles estejam renderizando um triângulo 3D, a GPU funciona em quads inteiros que esse triângulo cobre. Portanto, se um triângulo não cobrir todos os pixels de 8x8 no bloco (ou 4x4 no caso da nvidia), a GPU calculará a cor dos pixels descobertos e descartará o resultado. Em outras palavras, o poder de processamento de pixels descobertos é desperdiçado. Embora isso pareça um desperdício, funciona incrivelmente bom para renderizar grandes triângulos 3D quando emparelhado com um grande número de núcleos de GPU (informações mais detalhadas aqui: otimizando o rasterizador básico ).

Portanto, quando olharmos para a rasterização baseada em vetores, você perceberá que ao desenhar linhas, mesmo que sejam grossas, há um espaço em branco enorme. Um monte de poder de processamento desperdiçado, e mais importante largura de banda (que é a principal causa de consumo de energia, e muitas vezes um gargalo) Então, a menos que você está desenhando uma linha horizontal ou vertical com um múltiplo espessura de 8, e que se alinha perfeitamente a Limites de 8 pixels, muito poder de processamento e largura de banda serão desperdiçados.

A quantidade de "desperdício" pode ser reduzida calculando o casco a ser renderizado (como NV_path_rendering faz), mas a GPU ainda está restrita a blocos 8x8 / 4x4 (também provavelmente os benchmarks de GPU da NVIDIA escalam melhor com resoluções mais altas, a proporção pixels_covered / pixels_wasted é muito menor).

É por isso que muitas pessoas nem se preocupam com a "aceleração do vetor hw". GPUs simplesmente não são adequadas para a tarefa.

NV_path_rendering é mais uma exceção do que a norma, e eles introduziram o novo truque de usar o buffer de estêncil; que suporta compactação e pode reduzir significativamente o uso da largura de banda.

No entanto, continuo cético em relação ao NV_path_rendering e, com um pouco de pesquisa no Google, mostra que o Qt ao usar o OpenGL (também conhecido como o caminho recomendado) é significativamente mais rápido que o NV_path_rendering da NVIDIA: renderização do caminho NV Em outras palavras, os slides da NVIDIA estavam "acidentalmente" comparando a versão do XRender de Qt. Opa.

Em vez de argumentar que "tudo o desenho vetorial com aceleração hw é mais rápido", os desenvolvedores do Qt são mais honestos admitindo que o desenho vetorial acelerado HW nem sempre é melhor (veja como a renderização funciona explicada: Qt Graphics and Performance - OpenGL )

E não tocamos na parte dos gráficos vetoriais de "edição ao vivo", que exigem a geração de faixas triangulares em tempo real. Ao editar svgs complexos, isso pode realmente sobrecarregar seriamente.

Seja melhor ou não, depende muito dos aplicativos; quanto à sua pergunta original "por que ela não decolou", espero que seja respondida agora: há muitas desvantagens e restrições a serem levadas em conta, muitas vezes tornando muitas pessoas céticas e até podem enviesá-las para que não implementem uma .

update: Fui indicado que os números estão completamente fora da base, pois as GPUs mencionadas não rasterizam em blocos de 64x64 e 32x32, mas sim 8x8 = 64 e 4x4 = 16. Isso praticamente anula as conclusões do post. Em breve, atualizarei este post mais tarde com informações mais atualizadas.

Matias N Goldberg
fonte
2
Kilgard respondeu a essa postagem no blog de Zack Rusin no final dos comentários. Houve um erro de driver na versão que Rusin testou. O driver 3xx mais recente venceu o código de Rusin por um fator de 2x-4x. Rusin não respondeu depois disso.
Fizz
1
Observe também que agora há trabalho em andamento no Skia (biblioteca 2D do Google Chrome / Chromium) para oferecer suporte ao NV_path_rendering: code.google.com/p/chromium/issues/detail?id=344330 O problema é meio complicado porque o OpenGL ES não é totalmente compatível com NV_path_rendering.
Fizz
1
De acordo com a apresentação muito mais recente em on-demand.gputechconf.com/gtc/2014/presentations/… , também há trabalhos para adicionar NV_path_rendering ao Illustrator. Ele também diz que Skia já utiliza NV_path_rendering quando disponível (embora o relatório de bug I ligada no meu comentário anterior sugere que isso não funciona tão bem quanto se poderia esperar.)
Fizz
1
Também Chris Wilson (desenvolvedor de cairo e funcionário da Intel) tinha apenas boas coisas a dizer sobre NV_path_rendering; está basicamente na lista de desejos de cairo: lists.cairographics.org/archives/cairo/2013-March/024134.html
Fizz
25

Não acho que seja verdade que ninguém se preocupe com "gráficos vetoriais acelerados", como está escrito nesta resposta .

A Nvidia parece se importar um pouco. Além de Kilgard, que é o técnico principal do NV_path_rendering (a partir de agora NVpr para salvar meus dedos), o presidente da Khronos, Neil Trevett, que também é vice-presidente da Nvidia, promoveu o NVpr o máximo que pôde nos últimos anos; veja o talk1 , talk2 ou talk3 . E isso parece ter valido a pena. No momento da redação deste artigo, o NVpr agora é usado no Skia do Google (que por sua vez é usado no Google Chrome) e independentemente [do Skia] em uma versão beta do Adobe Illustrator CC (beta), de acordo com os slides de Kilgard no GTC14 ; também existem alguns vídeos das palestras: Kilgard's e Adobe's. Um desenvolvedor do Cairo (que trabalha na Intel) também parece interessado no NVpr. Os desenvolvedores do Mozilla / Firefox também experimentaram o NVpr e, de fato, se preocupam com os gráficos vetoriais acelerados por GPU, como mostra este talk show do FOSDEM14 .

A Microsoft também se importa bastante porque criou o Direct2D , que é amplamente utilizado [se você acredita que o Mozilla dev da conversa mencionada].

Agora, para chegar ao ponto da pergunta original: existem de fato algumas razões técnicas pelas quais o uso de GPUs para renderização de caminho não é simples. Se você quiser ler sobre como a renderização de caminho difere da geometria de vértice 3D padrão do pântano e o que torna a aceleração por GPU da renderização de caminho não trivial, Kilgard tem uma postagem muito boa, semelhante a FAQ , que infelizmente está oculta em algum lugar do fórum do OpenGL.

Para obter mais detalhes sobre como o Direct2D, NVpr e esse trabalho, você pode ler o artigo Siggraph 2012 de Kilgard , que obviamente se concentra no NVpr, mas também faz um bom trabalho pesquisando abordagens anteriores. Basta dizer que hacks rápidos não funcionam muito bem ... (como observou o texto da pergunta PSE.) Existem diferenças significativas de desempenho entre essas abordagens, conforme discutido nesse artigo e mostrado em algumas das primeiras demos de Kilgard, por exemplo, em esse vídeo . Devo também observar que o documento oficial de extensão NVpr detalha várias afinações de desempenho ao longo dos anos.

Só porque o NVpr não era tão bom no Linux em 2011 (em sua primeira implementação lançada), como disse o post de 2011 de Zack Rusin, do Qt, isso não significa que a aceleração de vetores / caminhos por GPU seja inútil como resposta do Sr. Goldberg parece ter inferido disso. Kilgard, de fato, respondeu ao final da postagem do blog com drivers atualizados mostrando uma melhoria de 2x-4x em relação ao código mais rápido do Qt e Rusin não disse nada depois disso.

A Valve Corp. também se preocupa com a renderização de vetor acelerada por GPU, mas de uma maneira mais limitada, relacionada à renderização de fonte / glifo. Eles tiveram uma implementação rápida e agradável de suavização de fontes grandes usando campos de distância assinados (SDF) acelerados por GPU apresentados no Siggraph 2007 , que é usado em seus jogos como TF; há uma demonstração em vídeo da técnica postada no YouTube (mas não tenho certeza de quem fez isso).

A abordagem do SDF viu alguns aprimoramentos de um dos desenvolvedores do Cairo & pango na forma de GLyphy ; seu autor deu uma palestra no linux.conf.au 2014. A versão muito longa que não assisti é que ele faz uma aproximação de curvas em arco das curvas de Bezier para tornar a computação SDF mais tratável no espaço vetorial (e não no raster) (a Valve fez a última). Mas mesmo com a aproximação arco-spline, o cálculo ainda era lento; ele disse que sua primeira versão rodava a 3 fps. Então, ele agora faz uma seleção baseada em grade para coisas "muito distantes", que parecem uma forma de LOD (nível de detalhe), mas no espaço SDF. Com essa otimização, suas demos rodavam a 60 fps (e provavelmente era limitado pelo Vsync). No entanto, seus shaders são incrivelmente complexos e ultrapassam os limites de hardware e drivers. Ele disse algo como: "para cada combinação de driver / sistema operacional, tínhamos que mudar as coisas". Ele também encontrou erros significativos em compiladores de shader, alguns dos quais foram corrigidos por seus respectivos desenvolvedores. Parece muito com o desenvolvimento de títulos de jogos AAA ...

Em outra questão, parece que a Microsoft encomendou / especificou um pouco do novo hardware da GPU para melhorar a implementação do Direct2D com o hardware usado pelo Windows 8, se disponível . Isso se chama rasterização independente de alvo ( TIR ), um nome que é um pouco enganador sobre o que as coisas realmente parecem fazer, que é explicitado no pedido de patente da Microsoft . A AMD afirmou que o TIR melhorou o desempenho em gráficos vetoriais 2D em cerca de 500% . E houve um pouco de "guerra de palavras" entre eles e a Nvidia porque as GPUs Kepler não a possuem, enquanto as GPUs baseadas em GCN da AMD o fazem. A Nvidia confirmouque este é realmente um pouco de hardware novo, não apenas algo que uma atualização de driver pode fornecer. A publicação no blog de Sinofsky tem mais alguns detalhes, incluindo algumas referências reais do TIR. Estou citando apenas os bits gerais da ideia:

para melhorar o desempenho ao renderizar geometria irregular (por exemplo, bordas geográficas em um mapa), usamos um novo recurso de hardware gráfico chamado Target Independent Rasterization, ou TIR.

O TIR permite que o Direct2D gaste menos ciclos de CPU no mosaico, para que ele possa dar instruções de desenho à GPU com mais rapidez e eficiência, sem sacrificar a qualidade visual. O TIR está disponível no novo hardware de GPU projetado para Windows 8 que suporta o DirectX 11.1.

Abaixo está um gráfico mostrando o aprimoramento de desempenho para renderizar geometria anti-serrilhada a partir de uma variedade de arquivos SVG em uma GPU DirectX 11.1 suportando TIR: [gráfico cortado]

Trabalhamos em estreita colaboração com nossos parceiros de hardware gráfico [leia AMD] para projetar o TIR. Melhorias dramáticas foram possíveis devido a essa parceria. O hardware DirectX 11.1 já está no mercado hoje e estamos trabalhando com nossos parceiros para garantir que mais produtos compatíveis com TIR estejam disponíveis amplamente.

Eu acho que essa foi uma das coisas legais que o Win 8 adicionou que foi perdida principalmente para o mundo no fiasco da UI do Metro ...

Efervescer
fonte
1
Parece um mr Paul Houx fez esse vídeo (siga o link)
SwiftsNamesake
Ótimas citações e recursos.
Startec
5

Provavelmente porque seus benefícios não superam os custos.


fonte
Desculpe por perguntas noob, mas, em geral, como você faz as coisas aparecerem na tela quando foi calculada pela CPU? Como a imagem a ser pós-processada estava disponível para a CPU em primeiro lugar? Você copiou os dados de pixels pelo barramento duas vezes?
cubuspl42
@ cubuspl42 Desculpas pela resposta super tardia, mas no software em que trabalhamos antes, ele estava usando o OpenGL de uma maneira em que estávamos adquirindo os pixels do buffer de quadros usando PBOs antes de exibir o resultado na janela. Isso incluiu algum trabalho redundante, mas foi uma limitação de um projeto herdado, construído ao redor de imagens rasterizadas através da CPU para uma janela. Como resultado da comparação da Bloom, meu colega escreveu seu frag shader antes de recuperar a imagem do buffer de quadros. Simplesmente fiz minha comparação aplicando o bloom na CPU à imagem adquirida.