Direct3D vs OpenGL: uma história de confronto

Até hoje, há um debate na Internet sobre qual é a melhor API gráfica: Direct3D ou OpenGL? Apesar de sua natureza religiosa, essas batalhas verbais trazem resultados úteis na forma de boas revisões históricas do desenvolvimento de gráficos acelerados por hardware.

image

O objetivo deste post é traduzir uma dessas excursões para a história.escrito por Jason L. McKesson em resposta à pergunta "Por que os desenvolvedores de jogos preferem o Windows"? É improvável que este texto responda à pergunta feita, mas ele descreve a história do desenvolvimento e o confronto das duas APIs gráficas mais populares de uma maneira muito colorida e bastante detalhada, por isso mantive a marcação do autor na tradução. O texto foi escrito em meados de 2011 e abrange um período que começa pouco antes do advento do Direct3D e até o momento da redação. O autor do texto original é um desenvolvedor de jogos experiente, participante ativo do StackOverflow e criador de um extenso livro de texto sobre a moderna programação gráfica 3D. Então vamos dar a palavra ao Jason.

Prefácio


Antes de começarmos, gostaria de dizer que sei mais sobre o OpenGL do que sobre o Direct3D. Na minha vida, não escrevi uma única linha de código no D3D, mas escrevi manuais do OpenGL. Mas o que eu quero falar não é uma questão de preconceito, mas de história.

O nascimento do conflito


Uma vez, no início dos anos 90, a Microsoft olhou em volta. Eles viram que o SNES e o Sega Genesis são muito legais, você pode jogar muitos jogos de ação e tudo mais. E eles viram os prós. Os desenvolvedores escreveram jogos dosovskie como console: perto do ferro. No entanto, diferentemente dos consoles, nos quais o desenvolvedor sabia que tipo de hardware o usuário teria, os desenvolvedores foram forçados a escrever sob muitas configurações. E isso é muito mais complicado do que parece.

Mas a Microsoft tinha um problema maior: o Windows. Veja bem, o Windows queria ter o hardware completamente, diferentemente do DOS, que permitia que os desenvolvedores fizessem qualquer coisa. A posse de ferro é necessária para a interação entre aplicações. Mas esse tipo de interação é exatamente o que eles odeiam.desenvolvedores de jogos porque consomem recursos preciosos que eles poderiam usar para todos os tipos de coisas legais.

Para promover o desenvolvimento de jogos no Windows, a Microsoft precisava de uma API uniforme que fosse de baixo nível, funcionaria no Windows sem perda de desempenho e seria compatível com vários hardwares . Uma única API para gráficos, som e dispositivos de entrada.

Então o DirectX nasceu.

Os aceleradores 3D apareceram alguns meses depois. E a Microsoft teve problemas. O fato é que o DirectDraw, um componente gráfico do DirectX, trabalhava apenas com gráficos 2D: alocava memória gráfica e fazia operações de bits rápidas entre diferentes setores da memória.

Portanto, a Microsoft comprou um software de terceiros e o transformou no Direct3D versão 3. Ele foi repreendidoabsolutamente tudo. E havia um motivo: a leitura do código no D3D v3 parecia uma decodificação da linguagem escrita de uma civilização antiga extinta.

O velho John Carmack, da Id Software, olhou para essa desgraça, disse "Sim, foi ..." e decidiu escrever usando outra API: OpenGL.

No entanto, o outro lado dessa história confusa é que a Microsoft trabalhou com a SGI para implementar o OpenGL para Windows. A idéia era atrair desenvolvedores de aplicativos GL típicos para estações de trabalho: CAD, sistemas de modelagem e similares. Os jogos foram a última coisa que eles pensaram. Isso preocupava principalmente o Windows NT, mas a Microsoft decidiu adicionar o OpenGL ao Windows 95 também.

Para atrair desenvolvedores de software para estações de trabalho no Windows, a Microsoft decidiu suborná-los com acesso a novos aceleradores 3D. Eles implementaram um protocolo para drivers de clientes instalados: uma placa de vídeo poderia substituir o software OpenGL da Microsoft pela implementação de hardware. O código usava automaticamente o hardware OpenGL, se disponível.

No entanto, naqueles dias, as placas gráficas dos consumidores não tinham suporte ao OpenGL. Isso não impediu o Carmack de portar o Quake para o OpenGL em uma estação de trabalho SGI. No arquivo leia-me do GLQuake, você pode ler o seguinte:
, glquake OpenGL, texture objects. , , , . - , .

( 1997), opengl , glquake , intergraph realizm. 3dlabs , . 3dlabs glint permedia NT , glquake 3dlabs.

3dfx opengl32.dll, glquake, opengl. opengl- , « glquake».

Este foi o nascimento de drivers miniGL. Eles finalmente evoluíram para implementações completas do OpenGL assim que o hardware se tornou poderoso o suficiente para suportar essa funcionalidade no hardware. A nVidia foi a primeira a oferecer uma implementação completa do OpenGL. Outros fornecedores ainda estavam lentos, o que foi um dos motivos da transição para o Direct3D, suportado por uma ampla gama de equipamentos. No final, apenas nVidia e ATI (que agora é AMD) permaneceram e ambas tiveram boas implementações em OpenGL.

Alvorecer do OpenGL


Assim, os participantes são definidos: Direct3D contra OpenGL. Esta é realmente uma história incrível, considerando o quão ruim o D3D v3 foi.

O OpenGL Architectural Review Board (ARB) é a organização responsável por manter e desenvolver o OpenGL. Eles lançam muitas extensões, contêm um repositório com extensões e criam novas versões da API. O ARB é um comitê composto por um grande número de participantes na indústria de computação gráfica e alguns fabricantes de sistemas operacionais. Apple e Microsoft também eram membros da ARB em momentos diferentes.

O 3Dfx entra em cena com seu Voodoo2. Esta é a primeira placa de vídeo que permite a criação de várias estruturas, que não eram fornecidas anteriormente no OpenGL. Enquanto o 3Dfx se opunha fortemente ao OpenGL, a nVidia, a próxima fabricante do chip multitexturing (TNT1), era louca pelo OpenGL. Em seguida, a ARB lançou a extensão GL_ARB_multitexture, que dava acesso a várias texturas.

Enquanto isso, o Direct3D v5 aparece. Agora, o D3D realmente se tornou uma API , não um tipo de bobagem. Qual é o problema? Na ausência de multi-extensão.

Opa

Mas isso não causou os inconvenientes possíveis, porque quase ninguém usou várias texturas. A multitexturação quase não prejudica o desempenho e, em muitos casos, a diferença é invisível no contexto da passagem múltipla. E, é claro, os desenvolvedores de jogos gostam muito de seus jogos funcionarem com confiança no hardware antigo, que não tinha suporte para várias texturas, então muitos jogos foram lançados sem ele.

D3D deu um suspiro de alívio.

O tempo passou e a nVidia lançou a GeForce 256 (que não deve ser confundida com a primeira GeForce GT-250), interrompendo a luta no mercado de placas gráficas pelos próximos dois anos. A principal vantagem competitiva dessa placa foi a capacidade de fazer transformações de vértices e iluminação (transformação e iluminação, T&L) em hardware. Mas isso não é tudo: nVidia OpenGL amou tanto que sua T & L-motor realmente sido OpenGL. Quase literalmente! Pelo que entendi, alguns de seus registros receberam diretamente valores numéricos de variáveis ​​do tipo GLenum.

O Direct3D v6 é lançado. Finalmente, várias texturas chegaram a tempo ... mas sem o T&L do hardware. OpenGL semprehavia um pipeline de T&L, embora antes do GeForce 256 fosse implementado em software. Portanto, para a nVidia, acabou sendo bastante simples refazer a implementação do software em uma solução de hardware. No D3D, os T&L de hardware apareceram apenas na sétima versão.

Amanhecer da Era Shader, OpenGL no Escuro


Depois veio a GeForce 3. Ao mesmo tempo, muitas coisas interessantes aconteceram.

A Microsoft decidiu que não se atrasariam mais. Portanto, em vez de examinar o que a nVidia fará e copiar seu desenvolvimento já pós-factum, a Microsoft tomou uma decisão incrível: vá e fale. E eles se apaixonaram e conseguiram um pequeno console comum.

O divórcio barulhento ocorreu mais tarde, mas esta é uma história completamente diferente.

Para o mercado de PCs, isso significava que o GeForce 3 saiu simultaneamente com o D3D v8, e é fácil ver como o GeForce 3 afetou os shaders do D3D v8. Os shaders de pixel do Shader Model 1.0 eram muitomuito afiada para equipamentos nVidia. Nenhuma tentativa foi feita para abstrair a nVidia do ferro. O Shader Model 1.0 foi projetado para a GeForce 3.

Quando a ATI entrou na corrida de desempenho gráfico com a Radeon 8500, havia um problema. O pipeline de Radeon 8500 pixels acabou sendo mais poderoso que a nVidia. Portanto, a Microsoft lançou o Shader Model 1.1, que era basicamente para o 8500.

Parece uma derrota no D3D, mas sucesso e fracasso são termos relativos. De fato, uma falha épica aguardava o OpenGL.

A NVidia gostava muito do OpenGL, então, após o lançamento da GeForce 3, eles lançaram várias extensões para o OpenGL. Proprietárioextensões que funcionavam apenas na nVidia. Naturalmente, quando a placa 8500 apareceu, ela não podia usar nenhuma delas.

Portanto, no D3D 8, você pode pelo menos executar os shaders SM 1.0. É claro que, para usar toda a frescura do 8500, tive que escrever novos shaders, mas pelo menos o código funcionou .

Para obter qualquer shaders no OpenGL Radeon 8500, ATI teve que desenvolver algumas extensões para OpenGL. Extensões proprietárias que funcionavam apenas na ATI. Como resultado, para que os desenvolvedores pudessem declarar que parafusavam shaders no mecanismo, eles precisavam escrever um código separado para a nVidia e um código separado para a ATI.

Você pode perguntar: "E onde estava o comitê ARB que deveria apoiar o OpenGL à tona?" E eles eram onde muitos comitês terminavam: sentavam-se e eram estúpidos.

Observe que mencionei ARB_multitexture acima porque esta extensão está profundamente envolvida em toda a situação. Pareceu a um observador externo que a ARB geralmente quer evitar a ideia de sombreadores. Eles decidiram que, se injetar configurabilidade suficiente em um pipeline fixo, ele será igual em seus recursos a um pipeline de shader programável.

A ARB lançou extensões uma a uma. Cada extensão com as palavras "texture_env" no nome era uma tentativa de consertar esse design antigo. Veja a lista de extensões: oito extensões foram lançadase muitas delas foram traduzidas para a funcionalidade básica do OpenGL.

Naquela época, a Microsoft fazia parte do ARB e o deixou apenas para o lançamento do D3D 9, então talvez a Microsoft sabotasse o OpenGL de alguma forma. Pessoalmente, duvido dessa teoria por duas razões. Primeiro, eles teriam que garantir o apoio de outros membros do Comitê, porque cada membro tem apenas um voto. Em segundo lugar, e mais importante, o Comitê não precisou da ajuda da Microsoft para estragar tudo, evidências que veremos mais adiante.

Como resultado, o ARB, provavelmente sob pressão da ATI e da nVidia (ambos são participantes ativos), finalmente acordou e introduziu os shaders de montagem no padrão.

Quer uma história ainda mais estranha?

Termos e condições de hardware. Isto é o que o OpenGL originalmente possuía.. Para obter o mais alto desempenho possível de T&L de hardware, é necessário armazenar dados de vértice na GPU. Ainda assim, a GPU é o principal consumidor de dados de vértices.

No D3D v7, a Microsoft introduziu o conceito de buffers de vértices, que alocam pedaços de memória na GPU e colocam os dados de vértices lá.

Deseja saber quando funcionalidades equivalentes apareceram no OpenGL? Sim, a nVidia, como a maior fã do OpenGL, lançou sua extensão para armazenar matrizes de vértices na GPU no tempo do lançamento da GeForce 256. Mas quando a ARB introduziu essa funcionalidade?

Dois anos depois. Foi depoisde como aprovou shaders de vértice e fragmento (pixel em termos de D3D). A ARB levou muito tempo para desenvolver uma solução multiplataforma para armazenar dados de vértices na memória da GPU. E é disso que o T&L de hardware precisa para obter o máximo desempenho.

Uma língua para matar todos eles


Então, o OpenGL está quebrado há algum tempo. Não havia sombreadores de plataforma cruzada e armazenamento de vértice independente de hardware na GPU, enquanto os usuários do D3D desfrutavam de ambos. Poderia piorar?

Você poderia dizer que sim. Conheça: 3D Labs .

Você pergunta: quem são eles? Eles são uma empresa morta que considero o verdadeiro assassino do OpenGL. Obviamente, o fracasso geral do Comitê tornou o OpenGL vulnerável, enquanto deveria destruir o D3D em pedaços. Mas, na minha opinião, o 3D Labs é talvez a única razão para a atual posição de mercado do OpenGL. O que eles fizeram para isso?

Eles desenvolveram uma linguagem de sombreador para o OpenGL.

A 3D Labs era uma empresa em extinção. Suas GPUs caras foram retiradas do mercado de estações de trabalho pela pressão cada vez maior da nVidia. E, diferentemente da nVidia, o 3D Labs não foi introduzido no mercado consumidor; A vitória da nVidia significaria a morte do 3D Labs.

O que finalmente aconteceu.

Em um esforço para flutuar em um mundo que não precisava de seus produtos, o 3D Labs apareceu na Game Developer Conference com uma apresentação do que eles chamavam de "OpenGL 2.0". Era uma API do OpenGL reescrita do zero. E isso fazia sentido, porque naqueles dias a API do OpenGL estava cheia de lixo (que, no entanto, permanece lá até hoje). Veja pelo menos quão esotericamente é feito o carregamento e encadernação de texturas.

Parte de sua proposta era de linguagem shader. Sim ele é. No entanto, diferentemente das extensões existentes entre plataformas, o idioma do sombreador era "alto nível" (C é um nível alto para o idioma do sombreador).

Ao mesmo tempo, a Microsoft estava trabalhando em sua própria linguagem de sombreador. Que eles, incluindo toda a sua imaginação coletiva, chamaram ... High Level Shader Language (HLSL). Mas a abordagem deles à linguagem era fundamentalmente diferente.

O maior problema com o 3D Labs era que ele era incorporável. A Microsoft determinou completamente seu próprio idioma. Eles lançaram um compilador que gerava código de montagem para shaders SM 2.0 (ou superior), que, por sua vez, podiam ser alimentados com o D3D. Nos dias do D3D v9, o HLSL nunca tocava diretamente no D3D. Ele era uma abstração boa, mas opcional. O desenvolvedor sempre teve a oportunidade de usar o exaustor do compilador e ajustá-lo para obter o desempenho máximo.

O 3D Labs não tinha nada disso. Você fornece ao driver uma linguagem do tipo C e ele cria um sombreador. Isso é tudo. Não há sombreador assembler, nada que possa ser alimentado com outra coisa. Somente um objeto OpenGL representando um sombreador.

Para os usuários do OpenGL, isso significava que eles eram propensos aos caprichos dos desenvolvedores do OpenGL que haviam acabado de aprender a compilar linguagens do tipo assembler. Os compiladores de linguagem de sombreador OpenGL (GLSL) têm estado furiosos com bugs. Para piorar as coisas, se você conseguisse compilar corretamente o shader em plataformas diferentes (o que por si só era uma grande conquista), ele ainda estava sujeito a otimizadores daqueles tempos que não eram tão ótimos quanto poderiam ser.

Essa foi uma grande, mas não a única desvantagem do GLSL. Longe do único.

No D3D, como nas antigas linguagens de montagem do OpenGL, era possível misturar e combinar shaders de vértice e fragmento de todas as maneiras possíveis. Você poderia usar qualquer shader de vértice com qualquer shader de fragmento compatível se eles interagissem através da mesma interface. Além disso, até alguma incompatibilidade foi permitida: por exemplo, o sombreador de vértice pode gerar um valor que não foi usado pelo sombreador de fragmento.

Não havia nada parecido no GLSL. Os shaders de vértice e fragmento se fundiram, formando algo chamado 3D Labs "objeto de software". Portanto, para o uso conjunto de vários shaders de vértice e fragmento em várias combinações, era necessário criar vários objetos de programa. Isso causou o segundo maior problema.

O 3D Labs achou que eram os mais inteligentes. Eles usaram o C / C ++ como base para o modelo de compilação GLSL. É quando você pega um arquivo c e o compila em um arquivo de objeto e, em seguida, pega vários arquivos de objeto e os compõe em um programa. É assim que o GLSL compila: primeiro você compila um vértice ou fragmento de sombreador em um objeto de sombreador, depois coloca esses objetos em um objeto de programa e os reúne para finalmente formar um programa.

Em teoria, isso permitia a exibição de coisas legais como shaders de “biblioteca” que contenham código chamado pelo shader principal. Na prática, isso resultou na compilação de shaders duas vezes: Uma vez na fase de compilação e uma segunda vez na fase de compilação. Em particular, o compilador da nVidia era famoso por isso. Não gerou nenhum código de objeto intermediário; ele compilou no início, jogou fora o resultado e compilou novamente na fase de compilação.

Assim, para conectar o shader de vértice a dois shaders de fragmento diferentes, foi necessário compilar muito mais do que no D3D. Especialmente considerando que toda a compilação é feita offline , e não antes que o programa seja executado diretamente.

GLSL teve outros problemas. Talvez seja errado culpar toda a falha no 3D Labs, porque no final a ARB aprovou e incluiu o idioma dos shaders no OpenGL (mas nada mais das sugestões do 3DLabs). No entanto, a ideia original ainda era para o 3D Labs.

E agora a coisa mais triste: o 3D Labs estava certo (principalmente). O GLSL não é uma linguagem vetorial como o HLSL na época. Isso aconteceu porque o hardware do 3D Labs era escalar (como o hardware moderno da nVidia) e eles estavam completamente certos ao escolher a direção que muitos fabricantes de equipamentos seguiram posteriormente.

Eles estavam certos com a escolha do modelo de compilação para o idioma "de alto nível". Até o D3D finalmente chegou a isso.

O problema é que o 3D Labs estava certo na hora errada . E, na tentativa de chegar ao futuro prematuramente, na tentativa de estar pronto para o futuro, eles deixam de lado o presente. Parece com a funcionalidade de T&L no OpenGL, que sempre esteve presente. Exceto que o pipeline do OpenGL T&L foi útile antes do advento do hardware T&L, o GLSL era um fardo antes que o resto do mundo o alcançasse.

GLSL é uma boa linguagem agora . Mas o que havia naquele tempo? Ele foi terrível. E o OpenGL sofreu com isso.

A caminho da apoteose


Apoio a opinião de que o 3D Labs deu um golpe mortal no OpenGL, mas o último prego no caixão foi marcado pela própria ARB.

Você pode ter ouvido essa história. Nos dias do OpenGL 2.1, o OpenGL tinha grandes problemas. Ele carregava uma enorme carga de compatibilidade. A API não era mais fácil de usar. Uma coisa pode ser feita de cinco maneiras diferentes e não está claro qual é a mais rápida. Você poderia "aprender" o OpenGL com tutoriais simples, mas não aprendeu o OpenGL que fornece potência e desempenho reais de gráficos.

A ARB decidiu fazer outra tentativa de inventar o OpenGL. Era como o “OpenGL 2.0” do 3D Labs, mas melhor porque o ARB estava por trás dessa tentativa. Eles chamavam de "Longs Peak".

O que há de tão ruim em gastar um pouco de tempo aprimorando a API? A má notícia é que a Microsoft está em uma posição bastante precária. Este era o momento de atualizar para o Vista.

No Vista, a Microsoft decidiu fazer alterações há muito tempo atrasadas nos drivers gráficos. Eles forçaram os motoristas a recorrer ao sistema operacional para virtualização da memória gráfica e muitos outros.

Você pode discutir por um longo tempo sobre os méritos dessa abordagem e se isso era possível, mas o fato permanece: a Microsoft criou o D3D 10 apenas para o Vista e superior. Mesmo em um hardware compatível com D3D, era impossível executar um aplicativo D3D sem o Vista.

Você deve se lembrar que o Vista ... digamos que não funcionou muito bem. Portanto, tínhamos um sistema operacional de lazer, uma nova API que funcionava apenas nesse sistema operacional e uma nova geração de hardware que precisava dessa API e sistema operacional para fazer algo mais do que simplesmente superar a geração anterior em desempenho.

No entanto, os desenvolvedores podem usar a funcionalidade de nível D3D 10 através do OpenGL. Ou seja, eles poderiam se a ARB não estivesse ocupada trabalhando em Long Peaks.

A ARB passou bons anos e meio a dois anos trabalhando na melhoria da API. Quando o OpenGL 3.0 foi lançado, a transição para o Vista terminou, o Windows 7 estava a caminho e os desenvolvedores de jogos não se preocupavam mais com a funcionalidade do D3D 10. No final, o equipamento para o D3D 10 funcionava perfeitamente com os aplicativos no D3D 9. Com o aumento no ritmo de transferência do PC para o D3D 9. console (ou com a transição dos desenvolvedores de PC para o mercado de consoles), os desenvolvedores precisavam cada vez menos da funcionalidade do D3D 10.

Se os desenvolvedores pudessem acessar essa funcionalidade mesmo no Windows XP, o desenvolvimento do OpenGL poderia ter uma carga vital de vivacidade. Mas a ARB perdeu esta oportunidade. Você quer saber o que é o pior?

ARB falhouinvente a API do zero, apesar de passar dois anos preciosos tentando fazê-lo. Portanto, eles retornaram o status quo, adicionando apenas um mecanismo para declarar a funcionalidade obsoleta.

Como resultado, a ARB não apenas perdeu as principais oportunidades, mas também falhou no trabalho que as levou a essa omissão. Foi uma falha épica em todas as direções.

Esta é a história do confronto entre o OpenGL e o Direct3D. A história de oportunidades perdidas, a maior estupidez, imprudência deliberada e absurdos banais.

Source: https://habr.com/ru/post/pt397309/


All Articles