7.0 KiB
В PlayStation 1 (PS1) передача видеокоманд через DMA в GPU — это ключевой механизм для эффективного рендеринга. Разберём процесс детально, включая работу с памятью.
1. Как передаются видеокоманды через DMA?
GPU PS1 не имеет собственного набора инструкций — он выполняет примитивные команды, переданные CPU. Эти команды организуются в цепочку DMA (Display List), которая указывает, что и как рисовать.
1.1. Структура цепочки команд
Каждая команда в цепочке состоит из:
- Слова-заголовка (указывает тип примитива: полигон, спрайт, настройка и т. д.).
- Данных (координаты, цвета, текстуры).
Пример команды для отрисовки треугольника:
typedef struct {
uint32_t header; // Тип примитива (например, POLY_F3)
uint16_t x1, y1; // Координаты
uint16_t x2, y2;
uint16_t x3, y3;
uint8_t r, g, b; // Цвет
} GPUPrimitive;
1.2. Передача через DMA
- CPU формирует цепочку команд в основной RAM (например, массив структур).
- Адрес этой цепочки передаётся в GPU через DMA.
- Используется порт
GP0(для команд) иGP1(для управления).
- Используется порт
- DMA-контроллер (канал GPU) копирует данные из RAM в GPU.
Код на ассемблере (пример):
; Запись адреса цепочки в DMA
li a0, 0x1F8010A0 ; Адрес регистра DMA_GPU (канал 2)
la a1, command_list ; Адрес цепочки команд в RAM
sw a1, 0(a0) ; Записываем адрес
; Настройка DMA
li a0, 0x1F8010A4
li a1, 0x01000200 ; Размер блока + флаги (например, 0x200 байт)
sw a1, 0(a0)
; Запуск DMA
li a0, 0x1F8010A8
li a1, 0x01000001 ; Включить DMA
sw a1, 0(a0)
2. Как GPU читает команды?
2.1. Отсутствие собственной памяти для команд
У GPU нет отдельной памяти для хранения команд (в отличие от современных GPU). Он:
- Читает команды напрямую из основной RAM через DMA.
- Интерпретирует их "на лету" (как потоковый процессор).
2.2. Роль FIFO-буфера
GPU имеет маленький FIFO-буфер (32 слова):
- DMA заполняет этот буфер, пока GPU читает данные.
- Если буфер переполняется, DMA приостанавливается.
3. Где хранятся данные?
3.1. Основная RAM (2 МБ)
- Цепочки команд хранятся здесь.
- Текстуры тоже могут быть в RAM (но чаще копируются в VRAM).
3.2. Видеопамять (VRAM, 1 МБ)
- Кадровый буфер (Frame Buffer) — хранит пиксели.
- Текстуры — загружаются сюда для быстрого доступа.
- CLUT (Color Look-Up Table) — палитры для 8-битных текстур.
3.3. Как GPU обращается к данным?
- Через DMA: Текстуры/данные копируются из RAM в VRAM перед рендерингом.
- Прямой доступ: GPU читает VRAM при отрисовке (например, текстуры).
4. Пример: полный цикл работы
- Подготовка:
- CPU создаёт в RAM массив команд (например,
DrawPolygon,LoadTexture). - Текстуры копируются в VRAM через
GP0или DMA.
- CPU создаёт в RAM массив команд (например,
- Запуск рендеринга:
- CPU отправляет адрес цепочки в DMA-контроллер GPU.
- DMA копирует команды из RAM в FIFO GPU.
- GPU выполняет команды, рисуя в кадровый буфер (VRAM).
- Вывод изображения:
- Видеоконтроллер выводит кадр из VRAM на экран.
5. Критические нюансы
- Синхронизация:
- Если GPU занят, DMA приостанавливается (проверяется через статусный регистр
GP1).
- Если GPU занят, DMA приостанавливается (проверяется через статусный регистр
- Оптимизация:
- Связные списки команд (OT — Ordering Table) позволяют сортировать примитивы.
- Ограничения:
- DMA может работать только с выровненными данными (адреса, кратные 4).
- Переполнение FIFO приводит к "пропущенным кадрам".
6. Псевдокод для работы с DMA и GPU
// 1. Загрузка текстуры в VRAM
void LoadTexture(uint16_t x, uint16_t y, void* tex_data) {
GP0_SendCommand(0xA0000000 | (y << 11) | x); // Адрес в VRAM
GP0_SendCommand(0x10000000 | (width * height)); // Размер
DMA_Start(GPU_CHANNEL, tex_data, size); // Копируем через DMA
}
// 2. Формирование цепочки команд
struct CommandList {
uint32_t prim_header;
uint32_t data[10];
} __attribute__((aligned(4))); // Выравнивание для DMA
// 3. Запуск рендеринга
void DrawFrame() {
CommandList list = { ... };
DMA_Start(GPU_CHANNEL, &list, sizeof(list));
GPU_TriggerDMA(); // Запуск выполнения
}
Итог
- DMA в PS1 передаёт адрес цепочки команд из RAM в GPU.
- GPU не имеет своей памяти для команд — читает их напрямую из RAM через DMA/FIFO.
- VRAM используется только для хранения текстур и кадрового буфера.
- Оптимизация DMA-передач критична для производительности.
Это объясняет, почему в демосценах PS1 так важны оптимизированные DMA-цепочки и ручное управление памятью. Для глубокого понимания изучите документацию PsyQ SDK или исходники open-source движков (например, PSn00bSDK).