Qual é o mecanismo que permite o cartão dual Nvidia Framebuffer Combinando sem SLI?

4

Primeiro, vamos nos certificar de que estamos todos na mesma página:

Como um pouco de informação de fundo, por favor saiba que quando você inicia um sistema operacional - qualquer sistema operacional - o BIOS (ou UEFI GOP) informa ao sistema operacional qual adaptador gráfico deve ser usado como o framebuffer primário . O framebuffer primário é basicamente uma região de memória virtual que, quando gravada, faz com que o driver gráfico inicie uma transferência de DMA para enviar dados de quadros para o dispositivo de saída de gráficos. Claramente, em uma configuração multi-GPU, não é tão simples, mas a idéia geral é que o sistema operacional em um nível básico só está ciente de um único framebuffer. Para os propósitos de decidir o que constitui um framebuffer, os monitores conectados à mesma placa gráfica são considerados acionados pelo mesmo framebuffer. Monitores conectados a cartões diferentes são, por padrão, orientados por diferentes framebuffers. Atualmente, existem vários truques técnicos que ajudam a preencher a lacuna de hardware entre diferentes framebuffers; daí a minha pergunta ...

Suponha que você tenha comprado mais monitores do que portas em qualquer uma das suas placas gráficas. Por exemplo, se sua placa gráfica tiver uma porta, você terá dois monitores. Se sua placa gráfica tiver duas portas, você terá três monitores. E assim por diante.

Assuma também que você não quer uma configuração Eyefinity ou similar, onde o sistema operacional trata todos os monitores como um "monitor grande".

Você faz deseja arrastar o mouse e o Windows entre monitores diferentes, sem problemas.

Formas de fazer isso:

  1. Ponte da placa gráfica física : Nvidia SLI ou AMD CrossFire. Essas soluções permitirão que você conecte seu (s) monitor (es) extra (s) a uma segunda placa gráfica discreta. As duas placas gráficas se comunicam entre si usando um hardware de bridge dedicado (ou, no caso da última geração de AMD Radeons, usando o barramento PCIe).

  2. Compartilhamento de framebuffer assistido por hardware de plataforma : Nvidia Optimus, AMD Enduro, LucidLogix Virtu MVP ... o conceito é o mesmo. Você tem monitor (es) conectados em um cartão (geralmente a placa-mãe, para usar o iGPU do processador) e monitor (es) conectado a uma placa gráfica discreta. Alguns chips na placa-mãe ajudam a coordenar e sincronizar essas duas placas gráficas separadas, de modo que o sistema operacional tenha a ilusão de apenas um buffer de quadros e, assim, você pode ter a configuração de vários monitores. Observe que algumas dessas soluções também podem controlar quais GPU os quadros são renderizados , não apenas o local em que os quadros de saída são rasterizados para .

  3. Software? : Se nenhuma das duas primeiras soluções de hardware estiver disponível, aparentemente ainda existe uma maneira de fazê-lo . Por exemplo, se sua placa-mãe não tiver Nvidia Optimus ou LucidLogix Virtu MVP; e seus cartões são não no SLI; você ainda pode pegar, digamos, uma Nvidia GTX 280 e uma Nvidia GT 210, conectá-las na mesma máquina e obter o mesmo resultado em termos de experiência do usuário em vários monitores. Você pode mover o mouse e as janelas entre os monitores sem problemas.

Minha pergunta é, na terceira opção acima, "Software?", como diabos isso funciona no Windows ? Além disso, qual é o mecanismo / recurso em particular chamado?

  • É um recurso do driver gráfico específico do fornecedor?
  • Ele é construído no próprio Windows?
  • Qual é a coisa maldita chamada?
por Horn OK Please 17.12.2013 / 23:12

2 respostas

2

Eu acho que você está confundindo 'framebuffer' e 'um grande monitor'. Você também está assumindo que o espaço do usuário pode acessar diretamente o framebuffer na placa gráfica.

Assuma o mais básico das janelas: uma imagem simples. Para o sistema operacional, isso é simplesmente um bloco de memória principal em que o espaço do usuário pode desenhar pixels. Quando sinalizado pelo sistema de janelas / sistema operacional, o driver gráfico copia esses pixels para o buffer de quadros da placa gráfica, no espaço / ordem correta.

No pseudo-código:

int* MAIN_FRAMEBUFFER;
int RESOLUTION_X, RESOLUTION_Y;
struct WINDOW = {
  int x, y;
  int width, height;
  int* pixels; // virtual framebuffer
}
WINDOW[] all_windows;
int nr_of_windows
void draw_all_windows() {
    for(int i=0; i<nr_of_windows; i++) {
       // transfer the virtual framebuffer of every window to the graphics card
       WINDOW w = all_windows[i];
       for(int y=w.y; y<w.y+w.height; y++) {
           memcpy(&w.pixels, &MAIN_FRAMEBUFFER + w.x + y*RESOLUTION_X, w.width);
       }
       // Draw window manager decoration
       ...
    }
}

Um driver da placa gráfica pode permitir que você faça essa operação memcpy com muito mais eficiência, por exemplo, simplesmente copiando a estrutura WINDOW para a memória da placa gráfica e fazendo a complicada cópia linha a linha no hardware.

Em uma configuração de vários monitores, basta repetir o processo para cada placa gráfica, copiando apenas a parte da janela que é exibida nesse monitor específico.

Mais uma vez, no pseudo-código:

int* MAIN_FRAMEBUFFER1;
int RESOLUTION_X, RESOLUTION_Y;
// assume FRAMEBUFFER2 is to the right of FRAMEBUFFER1, and they have the same resolution
// the pseudo-code can be extended to allow a different resolution and orientation
int* MAIN_FRAMEBUFFER2;
struct WINDOW = {
  int x, y;
  int width, height;
  int* pixels; // virtual framebuffer
}
WINDOW[] all_windows;
int nr_of_windows
void draw_all_windows() {
    for(int i=0; i<nr_of_windows; i++) {
       // transfer the virtual framebuffer of every window to the graphics card
       WINDOW w = all_windows[i];
       for(int y=w.y; y<w.y+w.height; y++) {
           if(w.x + w.width < RESOLUTION_X) {
               // fully on monitor 1
               memcpy(&w.pixels, &MAIN_FRAMEBUFFER1 + w.x + y*RESOLUTION_X, w.width);
           } else if (w.x > RESOLUTION_X) {
               // fully on monitor 2
               memcpy(&w.pixels, &MAIN_FRAMEBUFFER2 + (w.x - RESOLUTION_X) + y*RESOLUTION_X, w.width);
           } else {
               // split between monitor1 and monitor2
               int monitor1_w_width = RESOLUTION_X - w.x;
               memcpy(&w.pixels, &MAIN_FRAMEBUFFER1 + w.x + y*RESOLUTION_X, monitor1_w_width);
               memcpy(&w.pixels + monitor1_w_width, &MAIN_FRAMEBUFFER2 + monitor1_w_width + (w.x - RESOLUTION_X) + y*RESOLUTION_X, w.width - monitor1_w_width);
           }
       }
       // Draw window manager decoration
       ...
    }
}

Você poderia dizer que esse sistema é complicado. E, de fato, foi simplificado usando DirectDraw , que permite alocar imediatamente um bloco de memória no buffer de quadros da placa gráfica. No entanto, esse bloco está ligado a uma placa gráfica, e é por isso que você vê uma tela verde ao arrastar um reprodutor de mídia usando o DirectDraw para o segundo monitor.

Nota: Não tenho ideia de como isso funciona no Windows 7 ou em outros ambientes de janela 3D. Eu sei que eles escrevem o framebuffer da janela em uma textura e o renderizam em 3D. Talvez a textura seja copiada para a outra placa gráfica quando você move a janela?

Por fim, você se refere ao SLI ou a outros sistemas. Isso não tem nada a ver com renderização 2D. O que acontece é que você agrupa a memória de ambos os cartões. Em seguida, você instrui cada GPU a renderizar apenas uma parte da tela. A segunda placa gráfica (na qual nenhum monitor está conectado) grava o resultado de seus cálculos (pixels!) No buffer de quadros da placa gráfica principal, após o qual o chip VGA ou DVI envia isso para o monitor. A razão pela qual uma ponte é necessária é 1) copiar somente os dados de textura e modelo uma vez, mesmo que seja usada pelas GPUs e 2) para permitir que a segunda GPU grave os pixels no framebuffer da primeira.

Você também se refere ao Nvidia Optimus ea. Esse sistema é realmente muito semelhante ao SLI. No entanto, a ponte só é necessária para permitir que a segunda GPU grave pixels no framebuffer. Os chips não compartilham qualquer textura ou dados de vértice e não podem renderizar uma cena 3D em colaboração.

    
por 22.01.2014 / 22:11
0

A resposta de Parasietje está correta, mas talvez seja explicada pelo ponto de vista de alguém assumindo que você pode preencher as muitas lacunas.

O Windows em 2D não lida com vários monitores. O Windows lida com uma única superfície ou com várias estruturas distintas, mas ignora os monitores completamente, pois o framebuffer é manipulado inteiramente pela GPU sem intervenção ou intervenção do Windows. Tudo o que o Windows faz é descarregar um bitmap 2D para um local específico na memória que foi pré-atribuído como uma "zona quente" para um chip de framebuffer totalmente não relacionado para capturar as atualizações de tela. É por isso que você ainda recebe exibição se não tiver drivers. Sua BIOS irá configurar o modo VESA, definindo um local na memória para o despejo e nada mais. Isso ocorre porque uma GPU moderna é de vários dispositivos para o Windows. Um ou vários adaptadores de exibição + um acelerador de renderização + um núcleo de computação.

O problema está na sua pergunta. O Windows não tem envolvimento no exemplo 1 ou 2 além de dizer "iniciar SLI" para o adaptador.

Para torná-lo mais explícito. O Windows possui 'Virtual Displays' e 'Virtual Display Adapters' O primeiro pode ser uma conexão VNC ou RDP, já que eles não têm nada a fazer além de transmitir esses dados quando a imagem é criada. Isso para o Windows é o mesmo que escrever para esse endereço de memória e é usado para a imagem final.

O último é simplesmente um método definido pelo driver para despejar a imagem na tela, mas pode ser tão complexo quanto um framebuffer emulado saindo para uma porta SCSI através de renderização de software ou tão simples quanto um simples comando "mover para este endereço". Principalmente é pouco mais que o último. Isto é para obter a imagem final da sua memória para a sua tela.

O 3D é importante porque é assim que funciona em 2D e, portanto, por que seu cartão funcionará sem um driver. O Windows funciona em 2D, daí o nome. À esquerda para os subsistemas de saída do Windows e sua GPU nunca processará qualquer renderização, da mesma forma que sem o encadeamento, sua CPU nunca utilizará um segundo núcleo ... O Windows simplesmente não sabe o trabalho para enviá-lo ou até mesmo aceita o trabalho. Até mesmo a renderização 2D deve ser feita dessa maneira.

O

3D é muito mais complexo e proprietário para cada cartão e funciona via DirectX / OpenGL ou directDraw (que eu na maior parte DX agora) e para o Windows é uma caixa preta. É por isso que todas as placas têm que suportar internamente essas APIs para jogar ... O Windows simplesmente passa os drivers aos comandos que ele não entende. Ambas as APIs 3D 'conectam' a parte de processamento da sua GPU entre o renderizador 2D do Windows e o Virtual Display do Windows e, em seguida, conectam a exibição virtual por meio de drivers que contêm comandos proprietários à GPU. Quando digo proprietária btw, quero dizer códigos específicos de geração de VLIW / GCN / Geforce.

É assim que sua GPU, uma vez que possui drivers, é capaz de renderizar diretamente para seus próprios framebuffers e antes disso quando estiver no modo VESA, sua CPU está renderizando e gravando na RAM, então seu BIOS / EFI está passando da RAM para saída.

Também é por isso que seu dispositivo aparece no gerenciador de dispositivos como um e não como 3.

    
por 07.04.2017 / 17:16