4

Во-первых, давайте удостоверимся, что мы все на одной странице:

В качестве справочной информации, пожалуйста, знайте, что при запуске операционной системы - любой операционной системы - BIOS (или UEFI GOP) сообщает операционной системе, какой графический адаптер следует использовать в качестве основного кадрового буфера. Основной кадровый буфер - это, по сути, область виртуальной памяти, которая при записи в нее заставляет графический драйвер инициировать передачу DMA для отправки данных кадра на устройство вывода графики. Понятно, что в конфигурации с несколькими графическими процессорами все не так просто, но общая идея заключается в том, что операционная система на базовом уровне знает только об одном отдельном кадровом буфере. Для определения того, что представляет собой кадровый буфер, мониторы, подключенные к одной и той же графической карте, считаются управляемыми одним и тем же кадровым буфером. Мониторы, подключенные к разным картам, по умолчанию работают от разных кадровых буферов. Сегодня существует несколько технических приемов, которые помогают преодолеть аппаратный разрыв между различными кадровыми буферами; отсюда мой вопрос ...

Предположим, что вы приобрели больше мониторов, чем у вас есть портов на любой из ваших видеокарт. Например, если ваша видеокарта имеет один порт, у вас есть два монитора. Если ваша видеокарта имеет два порта, у вас есть три монитора. И так далее.

Также предположим, что вы не хотите использовать Eyefinity или аналогичную установку, где операционная система рассматривает все мониторы как один "большой монитор".

Вы хотите , чтобы иметь возможность перетаскивать мышью, и окно, между различными мониторами, без проблем .

Способы сделать это:

  1. Соединение физической видеокарты: Nvidia SLI или AMD CrossFire. Эти решения позволят вам подключить ваш «дополнительный монитор (и)» ко второй дискретной видеокарте. Две видеокарты обмениваются данными друг с другом с помощью специального аппаратного обеспечения моста (или, в случае AMD Radeon последнего поколения, с использованием шины PCIe).

  2. Совместное использование платформы с помощью аппаратного фрейм -буфера: Nvidia Optimus, AMD Enduro, LucidLogix Virtu MVP ... концепция такая же. Мониторы подключены к одной плате (обычно к материнской плате для использования процессора iGPU) и мониторы подключены к дискретной видеокарте. Некоторая микросхема на материнской плате помогает координировать и синхронизировать эти две отдельные видеокарты, так что операционная система имеет иллюзию только одного кадрового буфера, и, таким образом, вы можете настроить несколько мониторов. Обратите внимание, что некоторые из этих решений могут также контролировать, с какого графического процессора воспроизводятся кадры, а не только местоположение, в которое выходные кадры растеризуются.

  3. Программного обеспечения? Если ни один из первых двух аппаратных решений доступны, по- видимому, есть еще способ сделать это. Например, если на вашей материнской плате нет Nvidia Optimus или LucidLogix Virtu MVP; и ваши карты не в SLI; вы все еще можете взять, скажем, Nvidia GTX 280 и Nvidia GT 210, подключить их к одной и той же машине, и вы получите тот же результат с точки зрения работы с несколькими мониторами. Вы можете легко перемещать мышь и окна между мониторами.

Мой вопрос в третьем варианте выше: «Программное обеспечение?" Как, черт возьми, это работает на Windows? Кроме того, как называется этот конкретный механизм / функция?

  • Это особенность графического драйвера конкретного производителя?
  • Он встроен в саму Windows?
  • Как называется проклятая вещь?

2 ответа2

2

Я думаю, что вы путаете «кадровый буфер» и «один большой монитор». Вы также предполагаете, что пользовательское пространство может напрямую обращаться к кадровому буферу на видеокарте.

Предположим, самое простое из окон: простое изображение. Для ОС это просто блок основной памяти, в котором пользовательское пространство может рисовать пиксели. Когда сигнализируется ОС / оконной системой, графический драйвер копирует эти пиксели в кадровый буфер видеокарты в правильном пространстве / порядке.

В псевдокоде:

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
       ...
    }
}

Драйвер графической карты может позволить вам выполнить эту операцию memcpy гораздо более эффективно, например, просто скопировав структуру WINDOW в память видеокарты и выполнив сложное построчное копирование на аппаратном уровне.

При настройке нескольких мониторов вы просто повторяете процесс для каждой видеокарты, копируя только ту часть окна, которая отображается на этом конкретном мониторе.

Опять же, в псевдокоде:

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
       ...
    }
}

Можно сказать, что эта система сложна. И действительно, это было упрощено благодаря использованию DirectDraw , который позволяет сразу выделить блок памяти в кадровом буфере видеокарты. Однако этот блок привязан к одной видеокарте, поэтому при перетаскивании медиаплеера с помощью DirectDraw на второй монитор вы видите зеленый экран.

Примечание: я понятия не имею, как это работает в Windows 7 или других средах 3D-окон. Я знаю, что они пишут оконный фрейм-буфер в текстуре и отрисовывают его в 3D. Может быть, текстура копируется на другую видеокарту при перемещении окна?

Наконец, вы ссылаетесь на SLI или другие системы. Это не имеет ничего общего с 2D рендерингом. В результате вы объединяете память обеих карт. Затем вы указываете каждому графическому процессору визуализировать только часть экрана. Вторая видеокарта (к которой не подключен монитор) записывает результат своих вычислений (в пикселях!) в кадровый буфер основной видеокарты, после чего микросхема VGA или DVI проталкивает его на монитор. Причина, по которой требуется мост, заключается в том, чтобы: 1) копировать текстуру и данные модели только один раз, даже если он используется как графическим процессором, так и 2), чтобы позволить второму графическому процессору записывать пиксели в кадровый буфер первого.

Вы также ссылаетесь на Nvidia Optimus ea. Эта система на самом деле очень похожа на SLI. Однако мост необходим только для того, чтобы второй графический процессор мог записывать пиксели в кадровый буфер. Чипы не разделяют никакие текстуры или данные вершин и не могут визуализировать трехмерную сцену в сотрудничестве.

0

Ответ Парасие является правильным, но, возможно, он объяснен от лица, которое предполагает, что вы можете заполнить многие пробелы.

Windows в 2D не работает с несколькими мониторами. Windows работает с одной или несколькими дискретными поверхностями, но полностью игнорирует мониторы, поскольку кадровый буфер полностью обрабатывается графическим процессором без вмешательства и вмешательства Windows. Все, что делает Windows - это выдает 2d растровое изображение в определенное место в памяти, которое предварительно назначено в качестве «горячей зоны» для полностью несвязанного чипа кадрового буфера, чтобы захватывать обновления экрана. Вот почему вы все равно получаете дисплей, если у вас нет драйверов. Ваш BIOS настроит режим VESA, определив место в памяти, куда вы хотите создать дамп, и ничего больше. Это потому, что современный графический процессор - это несколько устройств для Windows. А или несколько адаптеров дисплея + ускоритель рендеринга + вычислительное ядро.

Проблема в вашем вопросе. В примере 1 или 2 Windows не участвует, кроме как сказать "запустить SLI" адаптеру.

Чтобы сделать это более явным. В Windows есть «Виртуальные дисплеи» и «Адаптеры виртуальных дисплеев». Первыми могут быть соединения VNC или RDP, так как им нечего делать, кроме как передавать эти данные после создания образа. Это для Windows аналогично записи в этот адрес памяти и используется для получения окончательного образа.

Последний - просто определяемый драйвером метод для вывода этого изображения на экран, но он может быть таким же сложным, как эмулируемый кадровый буфер, выводимый на порт SCSI посредством программного рендеринга, или так же просто, как простая команда "перейти к этому адресу". В основном это немного больше, чем последний. Это для получения окончательного изображения из вашей памяти на экран.

3D имеет значение, потому что именно так он работает в 2D и, следовательно, почему ваша карта будет работать без драйвера. Windows работает в 2D, отсюда и название. Если оставить на выходе подсистемы Windows, то ваш графический процессор никогда не будет обрабатывать рендеринг, так же как без многопоточности ваш процессор никогда не будет использовать второе ядро ... Windows просто не знает, какую работу отправлять или даже что она принимает работу. Даже 2D-рендеринг должен быть сделан таким образом.

3D гораздо более сложный и запатентованный для каждой карты и работает через DirectX/OpenGL или DirectDraw (который я в основном DX сейчас), а для Windows это черный ящик. Вот почему все карты должны внутренне поддерживать эти API, чтобы играть в игры ... Windows просто передает драйверам команды, которые она не понимает. Оба 3D API «подключают» обрабатывающую часть вашего графического процессора к Windows 2D рендереру и виртуальному дисплею Windows, а затем соединяют виртуальный дисплей с помощью драйверов, содержащих собственные команды, с графическим процессором. Когда я говорю «проприетарный», я имею в виду коды, специфичные для генерации VLIW/GCN/Geforce.

Таким образом, ваш графический процессор, если у него есть драйверы, может выполнять рендеринг непосредственно в свои собственные буферы кадров, и до этого, когда в режиме VESA ваш процессор выполняет рендеринг и запись в ОЗУ, тогда ваш BIOS/EFI передает его из ОЗУ на выход.

По этой же причине ваше устройство отображается в диспетчере устройств как одно, а не как 3.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .