Как интерфейс с видеокартой работает с C или C ++? - PullRequest
19 голосов
/ 01 ноября 2011

Библиотеки, такие как OpenGL, получают доступ к графической карте и могут создавать графические программы, как эти библиотеки получают доступ к графической карте, поскольку они реализованы с использованием C. Согласно тому, что я слышал, C и C ++ не предоставляют встроенные графические функцииязык и производство графики требуют библиотек.Как тогда эти библиотеки написаны на C?Тот же вопрос относится и к звуку?

Дополнительные функции для языков C / C ++, такие как графика, звук, доступ в Интернет, написаны на языках более низкого уровня, а затем предоставлены C / C ++ с использованием библиотек?

Я был бы благодарен за любое резюме, которое исправляет мои концепции, или за любые предлагаемые чтения в Интернете или книгах.

Ответы [ 2 ]

22 голосов
/ 01 ноября 2011

OpenGL на самом деле не библиотека. Это спецификация. Файлы opengl32.dll или libGL.so, которые есть в вашей системе, представляют собой очень тонкие слои, которые взаимодействуют с драйвером графического процессора.

Согласно тому, что я слышал, c и c ++ не предоставляют встроенные в язык графические функции, а для создания графики требуются библиотеки. Как тогда эти библиотеки написаны на c?

Операционная система предлагает функции для связи с оборудованием. Драйвер использует эти возможности для управления (отсюда и название) оборудованием. Например, запись последовательности A, B, C, D может заставить некоторый конкретный графический процессор нарисовать треугольник в буфере кадров.

Я объяснил эти вещи уже в В Windows, как OpenGL отличается от DirectX? и здесь Как OpenGL работает на самом низком уровне? (я включил дословную цитату здесь):

На этот вопрос почти невозможно ответить, потому что OpenGL сам по себе это просто интерфейс API, и до тех пор, пока реализация придерживается спецификация и результат соответствуют этому, это может быть сделано любым как вам нравится.

Возможно, вопрос заключался в следующем: как работает драйвер OpenGL на самый низкий уровень. Теперь на это опять невозможно ответить вообще, так как Драйвер тесно связан с какой-то частью оборудования, что может снова сделать все, однако разработчик разработал его.

Поэтому вопрос должен был звучать так: «Как это выглядит в среднем за сцены OpenGL и графической системы? ". Давайте посмотрим на это снизу вверх:

  1. На самом низком уровне находится графическое устройство. В настоящее время это графические процессоры, которые предоставляют набор регистров, управляющих их работой. (который регистрируется точно зависит от устройства) имеют некоторую программную память для шейдеров, объемной памяти для входных данных (вершин, текстур и т. д.) и канал ввода / вывода для остальной части системы, по которой он получает / отправляет потоки данных и команд.

  2. Графический драйвер отслеживает состояние графических процессоров и всех ресурсов прикладных программ, использующих графический процессор. И это отвечает за преобразование или любую другую обработку данных, отправленных приложения (преобразование текстур в формат пикселей, поддерживаемый GPU, компилировать шейдеры в машинный код GPU). Кроме того предоставляет некоторый абстрактный, зависимый от драйвера интерфейс для приложения программы.

  3. Затем есть зависимая от драйвера клиентская библиотека / драйвер OpenGL. В Windows это загружается через прокси через opengl32.dll, в Unix Системы это находится в двух местах: * X11 GLX модуль и драйвер зависимый драйвер GLX * и /usr/lib/libGL.so могут содержать некоторые драйверы зависимый материал для прямого рендеринга

    В MacOS X это "OpenGL Framework".

    Именно эта часть переводит вызовы OpenGL, как вы делаете это в вызовы к определенным функциям драйвера в описанной части драйвера в (2).

  4. Наконец, фактическая библиотека OpenGL API, opengl32.dll в Windows и в Unix /usr/lib/libGL.so; это в основном просто передает команды к реализации OpenGL.

То, как происходит фактическое общение, не может быть обобщено:

В Unix соединение 3 <-> 4 может происходить через сокеты (да, это может, и действительно идет по сети, если вы хотите) или через общий доступ Объем памяти. В Windows библиотека интерфейса и драйвер клиента оба загружаются в адресное пространство процесса, так что это не так уж много связь, но простые вызовы функций и передача переменных / указателей. В MacOS X это похоже на Windows, только без разделения между интерфейсом OpenGL и драйвером клиента (вот почему MacOS X не спешит отставать от новых версий OpenGL, всегда требуется полное обновление операционной системы для доставки нового рамки).

Связь между 3 <-> 2 может проходить через ioctl, чтение / запись или через отображение некоторой памяти в адресное пространство процесса и настройку MMU для запуска некоторого кода драйвера при каждом изменении этой памяти сделано. Это очень похоже на любую операционную систему, так как вы всегда нужно пересекать границу ядра / пользователя: в конечном итоге вы идете через какой-то системный вызов.

Связь между системой и графическим процессором происходит через периферийную шину и методы доступа, которые он определяет, так что PCI, AGP, PCI-E и т. д., которые работают через порт-ввод-вывод, ввод-вывод с отображением в память, DMA, IRQ.

Обновление

Чтобы ответить, как интерфейс взаимодействует с реальным оборудованием из программы на C, скажем, ядро ​​ОС и / или драйвер, написанный на C:

Сам стандарт C рассматривает адреса как нечто чисто абстрактное. Вы можете привести указатель к uintptr_t, но полученное вами числовое значение требуется только для соблюдения арифметики указателя, если приведено обратно к указателю. В противном случае значение может быть не связано с адресным пространством. Единственный безопасный способ реализовать аппаратный доступ к C - это написать материал самого низкого уровня в сборке, следуя ABI используемой реализации C и системы.

Вот как все соответствующие ОС делают это. Никогда адреса не указываются в C! Операционная система реализовала это в ассемблере, сопоставленном с компилятором C системы. Код, написанный на ассемблере, экспортируется как функции, вызываемые на C. Затем ядро ​​предоставляет эти функции драйверу GPU. Итак, цепочка:

Прикладная программа → [Уровень API OpenGL → Внедрение OpenGL поставщика] → Драйвер графического процессора → Ядро ОС → Аппаратное обеспечение.

3 голосов
/ 01 ноября 2011

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

C отлично справляется с доступом к памяти, поэтому он полностью подходит для чтения и записи напрямую с помощью аппаратного обеспечения. Ключевое слово volatile предназначено для того, чтобы явно помешать компилятору выполнять короткие действия и принудительно запрашивать соответствующие адреса. Это связано с тем, что сопоставленные с памятью адреса ввода-вывода могут неожиданно измениться и не вести себя как обычная оперативная память.

В простой системе этот низкоуровневый доступ к памяти для установки адресов будет абстрагирован в более легкую в использовании библиотеку. В современных операционных системах ядро ​​должно обеспечивать доступ к общим ресурсам, таким как графическая карта. Это означает, что ядро ​​будет реализовывать ввод-вывод, отображаемый в памяти, а также выполнять ряд системных вызовов (часто с использованием конструкций Swiss Army Knife, таких как ioctl), чтобы пользовательский процесс мог получить доступ к периферийному устройству. Это, в свою очередь, будет помещено в удобную удобную библиотеку, такую ​​как OpenGL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...